opendal

package
v0.40.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Overview

Package opendal 提供 OpenDAL 风格的存储抽象。

为什么不用真正的 OpenDAL Go binding?

  1. 真正的 OpenDAL Go binding(github.com/apache/opendal/bindings/go)只提供 Linux 预编译库(libopendal_c.linux.amd64.so.zst),macOS 编译会失败: `undefined: libopendalZst`
  2. 需 libffi 系统库 + 单独安装每个 scheme 的 companion module(s3/oss/cos/...)
  3. 部署复杂度高,团队上手成本大

解决方案:

  • OpenDAL 风格 API(Read/Write/Stat/Delete/List/Copy/Rename/CreateDir/RemoveAll)
  • scheme + options 统一配置(OpenDAL 风格)
  • 内部 dispatch:fs 走本地文件系统;s3/webdav 由 Driver 接口驱动 (s3 → minio-go,webdav → gowebdav,见 s3.go / webdav.go)
  • 当真正 OpenDAL Go binding 能在 macOS/Windows 跑通时,可替换 backend 实现(保持 interface 不变)

支持的 scheme(OpenDAL 命名约定):

fs       - 本地文件系统
s3       - AWS S3 / 兼容 S3 协议(MinIO/Ceph/OSS/COS/B2/...)
webdav   - WebDAV(含坚果云/Nextcloud/Alist)
oss/cos/obs/azblob/gcs/sftp/hdfs/memory - 扩展点,未配置驱动时按 fs 兜底

Index

Constants

View Source
const MaxWholeReadBytes = 50 << 20

MaxWholeReadBytes 「整读」(Read/GetFile)路径的硬上限(core#118):50MiB。

锚定预览上限的默认值(preview/service.go:max_preview_size 默认 50MB)—— 整读只服务「取内容」类消费:MCP 下载有 PB_MCP_MAX_FILE_SIZE(默认 6MB)前置 上限、文本分享内容在库(file_codes.text)不经存储整读、预览走流式 Reader + 自身上限;下载链路本就走流式。50MiB 覆盖全部合法整读消费。

刻意**不**做成配置:配置语义允许 0=不限(preview.MaxFileSize 的口径),而本 常量是 OOM 面的硬顶——远端后端(SFTP/FTP/OneDrive)整读还叠加网络缓冲, 多并发整读下内存峰值 ≈ 并发数 × 对象大小,必须与配置漂移解耦。

Variables

View Source
var ErrRangeUnsupported = errors.New("storage driver: range read unsupported")

ErrRangeUnsupported 当前驱动不支持按字节区间读取。 调用方(Range 下载/断点续传)应回退全量流式(200)。

View Source
var ErrReadTooLarge = errors.New("storage: 对象超过整读上限")

ErrReadTooLarge 整读超限(core#118)。调用方用 errors.Is 判断; storage 包有同名转发(storage.ErrReadTooLarge)。

Functions

func Probe

func Probe(ctx context.Context, op *Operator) error

Probe 认证级连通性验证:s3 校验凭据+桶存在;webdav 校验根路径可达; 其他 scheme(含 fs)直接通过。管理端切换/保存存储配置前调用。

func ReadAllLimited added in v0.40.0

func ReadAllLimited(r io.Reader, max int64) ([]byte, error)

ReadAllLimited 限量整读(core#118):最多整读 max 字节;恰好 max 字节放行, 超出(哪怕 1 字节)返回 ErrReadTooLarge——**显式报错而非静默截断**(截断会把 半个对象当完整内容交给上层:预览/取内容少半截、按残缺数据做完整性判定)。

实现:io.LimitReader(max+1) 多读 1 字节作超限哨兵(不先 Stat 再读——Stat 与 读之间对象可变,且部分驱动的 Stat 与读不同源)。

func SetDefault

func SetDefault(op *Operator)

SetDefault 设置默认 operator

Types

type Config

type Config struct {
	Scheme  Scheme
	Root    string            // scheme=fs 时为本地路径;scheme=s3 时为 bucket 名
	Options map[string]string // 通用 options(按 scheme 解释,见 s3.go/webdav.go)
}

Config 构造配置

type Driver

type Driver interface {
	Write(ctx context.Context, key string, data []byte) error
	// WriteStream 流式写入;size 为确切字节数(调用方先 Stat 求和得到)
	WriteStream(ctx context.Context, key string, r io.Reader, size int64) error
	Read(ctx context.Context, key string) ([]byte, error)
	Reader(ctx context.Context, key string) (io.ReadCloser, error)
	Stat(ctx context.Context, key string) (*Metadata, error)
	Delete(ctx context.Context, key string) error
	// RemoveAll 递归删除 key 前缀/目录;实现必须拒绝空 key(防全量误删)
	RemoveAll(ctx context.Context, key string) error
}

Driver 远端 scheme(s3/webdav 等)的底层驱动接口。 Operator 在 New 时按 scheme 构造具体驱动;NewCustom 允许测试注入假驱动。 key 一律为相对路径(无前导 /,不含 bucket/远端 root 前缀)。

type Metadata

type Metadata struct {
	Path    string
	Size    int64
	IsDir   bool
	ModTime time.Time
	ETag    string
}

Metadata 文件元数据

type Operator

type Operator struct {
	// contains filtered or unexported fields
}

Operator 存储操作器(OpenDAL 风格)

func GetDefault

func GetDefault() *Operator

GetDefault 获取默认 operator

func New

func New(cfg Config) (*Operator, error)

New 创建 Operator。

s3/webdav 的连接参数缺失/非法时返回 error——不再静默回退 fs, 「配置保存成功但实际读写落本地盘」正是拆分前遗留的假开关问题。 未知 scheme 仍按 fs 兜底(真正 OpenDAL binding 接入后改为返回 error)。

func NewCustom

func NewCustom(scheme Scheme, d Driver) *Operator

NewCustom 用外部注入的驱动创建 Operator(测试专用:注入假驱动验证分派逻辑)。

func (*Operator) Copy

func (op *Operator) Copy(ctx context.Context, src, dst string) error

Copy 复制文件。

FS 分支**流式**拷贝(core#140,core#118 同族残留收口):原 os.ReadFile 把源 文件整读进内存再写出——本地→本地拷贝峰值内存 ≈ 文件大小(无界整读面)。 拷贝不是「取内容」消费,**刻意不套** MaxWholeReadBytes 整读上限(封顶会砍掉 合法大文件拷贝),改为打开两端 io.Copy 流式推进:峰值内存 = io.Copy 的固定 缓冲,与文件大小无关。

func (*Operator) CreateDir

func (op *Operator) CreateDir(ctx context.Context, path string) error

CreateDir 创建目录(对象存储无目录概念时为 no-op)

func (*Operator) Delete

func (op *Operator) Delete(ctx context.Context, path string) error

Delete 删除文件

func (*Operator) Exists

func (op *Operator) Exists(ctx context.Context, path string) bool

Exists 检查文件是否存在

func (*Operator) List

func (op *Operator) List(ctx context.Context, path string) ([]*Metadata, error)

List 列出目录下的所有条目(驱动未实现时返回错误)

func (*Operator) Presign

func (op *Operator) Presign(ctx context.Context, req PresignedRequest) (*PresignedResult, error)

Presign 生成预签名 URL。

s3:由 minio-go 离线签名生成真实 S3 预签名 URL(客户端可直传直下)。 其余 scheme:回退为拼自家直传 URL(走自家服务中转,见 presign 域)。

func (*Operator) Read

func (op *Operator) Read(ctx context.Context, path string) ([]byte, error)

Read 读取整个文件(限量整读,core#118:超 MaxWholeReadBytes 显式报错)

func (*Operator) ReadRange

func (op *Operator) ReadRange(ctx context.Context, path string, start, length int64) (io.ReadCloser, error)

ReadRange 读取 [start, start+length) 字节区间(断点续传/Range 下载)。 length<=0 表示读到末尾。驱动未实现区间读能力时返回 ErrRangeUnsupported。

func (*Operator) Reader

func (op *Operator) Reader(ctx context.Context, path string) (io.ReadCloser, error)

Reader 获取流式读取器

func (*Operator) RemoveAll

func (op *Operator) RemoveAll(ctx context.Context, path string) error

RemoveAll 递归删除

func (*Operator) Rename

func (op *Operator) Rename(ctx context.Context, src, dst string) error

Rename 重命名/移动

func (*Operator) Scheme

func (op *Operator) Scheme() Scheme

Scheme 返回当前 scheme

func (*Operator) Stat

func (op *Operator) Stat(ctx context.Context, path string) (*Metadata, error)

Stat 获取文件元信息;对象不存在时返回包装了 os.ErrNotExist 的错误

func (*Operator) Write

func (op *Operator) Write(ctx context.Context, path string, data []byte) error

Write 写入数据

func (*Operator) WriteStream

func (op *Operator) WriteStream(ctx context.Context, path string, r io.Reader, size int64) error

WriteStream 流式写入(size 为确切字节数;fs 直接 create+copy)

type PresignedRequest

type PresignedRequest struct {
	Path   string            // 对象 key
	Method string            // PUT / GET
	Expire time.Duration     // 过期时间
	Opts   map[string]string // 额外选项(content-type, content-md5, ...)
}

PresignedRequest 预签名请求

type PresignedResult

type PresignedResult struct {
	URL     string            // 预签名 URL
	Method  string            // HTTP method
	Headers map[string]string // 需要附加的 header
	Expire  time.Time         // 过期时间
}

PresignedResult 预签名结果

type Scheme

type Scheme string

Scheme 存储方案(OpenDAL 命名约定)

const (
	SchemeFS       Scheme = "fs"
	SchemeS3       Scheme = "s3"
	SchemeOSS      Scheme = "oss"
	SchemeCOS      Scheme = "cos"
	SchemeOBS      Scheme = "obs"
	SchemeAzBlob   Scheme = "azblob"
	SchemeGCS      Scheme = "gcs"
	SchemeWebDAV   Scheme = "webdav"
	SchemeSFTP     Scheme = "sftp"
	SchemeFTP      Scheme = "ftp"
	SchemeHDFS     Scheme = "hdfs"
	SchemeOneDrive Scheme = "onedrive"
	SchemeMemory   Scheme = "memory"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址