package aliyun import ( "context" "errors" "fmt" "io" "strings" "git.apinb.com/ops/files/internal/storage" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" ) // Open 返回对象存储中的只读内容流。 func (c *Client) Open(ctx context.Context, objectKey string, byteRange *storage.ByteRange) (io.ReadCloser, error) { if strings.TrimSpace(objectKey) == "" { return nil, fmt.Errorf("对象键不能为空") } request := &oss.GetObjectRequest{ Bucket: oss.Ptr(c.bucket), Key: oss.Ptr(objectKey), } if byteRange != nil { rangeHeader := fmt.Sprintf("bytes=%d-%d", byteRange.Start, byteRange.End) request.Range = &rangeHeader } result, err := c.client.GetObject(ctx, request) if err != nil { return nil, fmt.Errorf("读取对象: %w", err) } if result == nil || result.Body == nil { return nil, fmt.Errorf("对象内容为空") } return result.Body, nil } func (c *Client) Stat(ctx context.Context, objectKey string) (storage.ObjectInfo, error) { if strings.TrimSpace(objectKey) == "" { return storage.ObjectInfo{}, fmt.Errorf("对象键不能为空") } result, err := c.client.GetObjectMeta(ctx, &oss.GetObjectMetaRequest{ Bucket: oss.Ptr(c.bucket), Key: oss.Ptr(objectKey), }) if err != nil { var serviceError *oss.ServiceError if errors.As(err, &serviceError) && serviceError.Code == "NoSuchKey" { return storage.ObjectInfo{}, storage.ErrObjectNotFound } return storage.ObjectInfo{}, fmt.Errorf("查询对象元数据: %w", err) } if result == nil { return storage.ObjectInfo{}, fmt.Errorf("对象元数据为空") } if result.ContentLength < 0 { return storage.ObjectInfo{}, fmt.Errorf("对象大小无效: %d", result.ContentLength) } if result.ETag == nil { return storage.ObjectInfo{}, fmt.Errorf("对象 ETag 缺失") } etag := strings.TrimSpace(strings.Trim(strings.TrimSpace(*result.ETag), "\"")) if etag == "" { return storage.ObjectInfo{}, fmt.Errorf("对象 ETag 无效") } if result.LastModified == nil || result.LastModified.IsZero() { return storage.ObjectInfo{}, fmt.Errorf("对象最后修改时间缺失") } return storage.ObjectInfo{ Size: result.ContentLength, StorageETag: etag, LastModified: *result.LastModified, }, nil } func (c *Client) Delete(ctx context.Context, objectKey string) error { if strings.TrimSpace(objectKey) == "" { return fmt.Errorf("对象键不能为空") } _, err := c.client.DeleteObject(ctx, &oss.DeleteObjectRequest{ Bucket: oss.Ptr(c.bucket), Key: oss.Ptr(objectKey), }) if err != nil { return fmt.Errorf("删除对象: %w", err) } return nil } func (c *Client) Status(ctx context.Context) (storage.RuntimeStatus, error) { _, err := c.client.ListObjectsV2(ctx, &oss.ListObjectsV2Request{Bucket: oss.Ptr(c.bucket), MaxKeys: 1}) if err != nil { return storage.RuntimeStatus{Provider: c.Provider(), Container: c.Container()}, fmt.Errorf("检查 OSS 存储状态: %w", err) } return storage.RuntimeStatus{Provider: c.Provider(), Container: c.Container(), Writable: true}, nil }