一个厂商中立的存储库。
只需一次编写,即可在任意存储服务中运行。
package main
import (
"log"
"go.beyondstorage.io/v5/services"
"go.beyondstorage.io/v5/types"
// 添加 fs 支持
_ "github.com/beyondstorage/go-service-fs/v3"
// 添加 s3 支持
_ "github.com/beyondstorage/go-service-s3/v2"
// 添加 gcs 支持
_ "github.com/beyondstorage/go-service-gcs/v2"
// 添加 azblob 支持
_ "github.com/beyondstorage/go-service-azblob/v2"
// 更多支持,可在 BeyondStorage 下获取
_ "github.com/beyondstorage/go-service-xxx"
)
func main() {
// 使用连接字符串初始化 storager
store, err := services.NewStoragerFromString("s3://bucket_name/path/to/workdir")
if err != nil {
log.Fatalf("service init failed: %v", err)
}
// 将 io.Reader 中的数据写入 hello.txt
n, err := store.Write("hello.txt", r, length)
// 从 hello.txt 中读取数据到 io.Writer
n, err := store.Read("hello.txt", w)
// 检查 hello.txt 是否存在并获取其元数据
o, err := store.Stat("hello.txt")
// 使用对象的函数获取元数据
length, ok := o.GetContentLength()
// List 将创建路径下对象的迭代器
it, err := store.List("path")
for {
// 使用迭代器检索下一个对象,直到迭代完成
o, err := it.Next()
if errors.Is(err, types.IteraoorDone) {
break
}
}
// 删除 hello.txt
err = store.Delete("hello.txt")
}
更多示例可以在 go-storage-example 找到。
目前已经有 16 个稳定的服务通过了所有的 集成测试。
另有 3 个公测版本的服务已实现了所需功能,但还没有通过 集成测试。
最后还有 4 个处于内测阶段的服务仍在开发中。
更多关于服务的想法可以在 Service Integration Tracking 找到。
基本操作
storager 元数据 meta := store.Metadata()
_ := meta.GetWorkDir() // 获取对象的工作目录
_, ok := meta.GetWriteSizeMaximum() // 获取写操作的最大尺寸
对象 的内容// 在偏移量 1024 处读取 2048 字节到 io.Writer
n, err := store.Read("path", w, pairs.WithOffset(1024), pairs.WithSize(2048))
对象 中// 从 io.Reader 写入 2048 字节
n, err := store.Write("path", r, 2048)
对象 元数据并检查是否存在o, err := store.Stat("path")
if errors.Is(err, services.ErrObjectNotExist) {
// 对象不存在
}
length, ok := o.GetContentLength() // 获取对象的内容长度
对象err := store.Delete("path") // 删除对象 "路径"
对象 it, err := store.List("path")
for {
o, err := it.Next()
if err != nil && errors.Is(err, types.IteratorDone) {
// 列表结束
}
length, ok := o.GetContentLength() // 获取对象的内容长度
}
扩展操作
对象 到 storagererr := store.(Copier).Copy(src, dst) // 从 src 复制一个对象到 dst
对象 到 storagererr := store.(Mover).Move(src, dst) // 从 src 移动一个对象到 dst
对象 生成一个可访问的公共 urlurl, err := store.(Reacher).Reach("path") // 生成一个对象的 url
对象 目录o, err := store.(Direr).CreateDir("path") // 创建一个对象目录
大文件操作
ms := store.(Multiparter)
// 创建一个分段对象
o, err := ms.CreateMultipart("path")
// 将 io.reader 中的 1024 字节分段写入索引 1
n, part, err := ms.WriteMultipart(o, r, 1024, 1)
// 完成分段对象创建
err := ms.CompleteMultipart(o, []*Part{part})
as := store.(Appender)
// 创建一个可追加的对象
o, err := as.CreateAppend("path")
// 从 io.Reader 写入 1024 字节
n, err := as.WriteAppend(o, r, 1024)
// 提交一个待追加的对象
err = as.CommitAppend(o)
bs := store.(Blocker)
// 创建一个块对象
o, err := bs.CreateBlock("path")
// 将 io.reader 中的 1024 字节写入 id 为 ”id-abc“ 的块
n, err := bs.WriteBlock(o, r, 1024, "id-abc")
// 通过块 id 组合区块
err := bs.CombineBlock(o, []string{"id-abc"})
ps := store.(Pager)
// 创建一个页面对象
o, err := ps.CreatePage("path")
// Write 1024 bytes from io.Reader at offset 2048
n, err := ps.WritePage(o, r, 1024, 2048)
全局对象元数据
id: 服务中的唯一键name: 服务工作目录的相对路径mode: 对象的模式可以由以下几种进行组合:read, dir, part 以及 更多 etag: 实体标签,定义于 rfc2616 content-length: 对象的内容大小content-md5: rfc2616 中定义的 Md5 简介content-type: rfc2616 中定义的媒体类型last-modified: 对象的最后更新时间系统对象元数据
服务系统对象元数据,如 storage-class 等。
o, err := store.Stat("path")
// 通过 go-service-s3 提供的 API 获取服务系统元数据
om := s3.GetObjectSystemMetadata(o)
_ = om.StorageClass // 此对象的存储类型
_ = om.ServerSideEncryptionCustomerAlgorithm // 此对象的 sse 算法
自我维护的代码生成器 定义 有助于生成我们所有的 API、pairs 和元数据。
生成的 pairs 可用作 API 的可选参数。
func WithContentMd5(v string) Pair {
return Pair{
Key: "content_md5",
Value: v,
}
}
生成的对象元数据可用于从对象中获取内容 md5。
func (o *Object) GetContentMd5() (string, bool) {
o.stat()
if o.bit&objectIndexContentMd5 != 0 {
return o.contentMd5, true
}
return "", false
}
支持通过 system pair 和 system metadata 指定在服务端对数据进行加密编码, 并且我们可以通过 Default Pairs 来简化工作。
func NewS3SseC(key []byte) (types.Storager, error) {
defaultPairs := s3.DefaultStoragePairs{
Write: []types.Pair{
// 要求密钥的加密算法必须为 AES256
s3.WithServerSideEncryptionCustomerAlgorithm(s3.ServerSideEncryptionAes256),
// 你的 AES-256 密钥, 必须具有 32 个字节长度
s3.WithServerSideEncryptionCustomerKey(key),
},
// 现在你必须提供客户密钥才能读取加密数据
Read: []types.Pair{
// 要求密钥的加密算法必须为 AES256
s3.WithServerSideEncryptionCustomerAlgorithm(s3.ServerSideEncryptionAes256),
// 你的 AES-256 密钥, 必须具有 32 个字节长度
s3.WithServerSideEncryptionCustomerKey(key),
}}
return s3.NewStorager(..., s3.WithDefaultStoragePairs(defaultPairs))
}
$ claude mcp add go-storage \
-- python -m otcore.mcp_server <graph>