package file import ( "context" "errors" "fonchain-fiee/api/files" "fonchain-fiee/pkg/service" "io" ) type grpcReaderSeeker struct { io.Reader io.Seeker path string userSpacePath string cursor int64 length int64 FileName string } func (g *grpcReaderSeeker) Seek(offset int64, whence int) (int64, error) { var abs int64 switch whence { case io.SeekStart: abs = offset case io.SeekCurrent: abs = g.cursor + offset case io.SeekEnd: abs = g.length + offset default: return 0, errors.New("grpc.Reader.Seek: invalid whence") } if abs < 0 { return 0, errors.New("grpc.Reader.Seek: negative position") } g.cursor = abs return abs, nil } func (g *grpcReaderSeeker) Read(b []byte) (n int, err error) { if g.cursor >= g.length { return 0, io.EOF } data, err := g.getBytesData(len(b)) if err != nil { return 0, err } n = copy(b, data) g.cursor += int64(n) return } // 通过grpc获取到bytes数据 func (g *grpcReaderSeeker) getBytesData(len int) ([]byte, error) { resp, err := service.FilesProvider.ResumableTransfer(context.TODO(), &files.ResumableTransferReq{ UserSpacePath: g.userSpacePath, Path: g.path, Offset: g.cursor, Length: int64(len), }) if err != nil { return nil, err } return resp.Content, nil } // grpc 获取到文件信息 func (g *grpcReaderSeeker) initInfo() error { resp, err := service.FilesProvider.Info(context.TODO(), &files.FileInfoReq{ UserSpacePath: g.userSpacePath, Path: g.path, }) if err != nil { return nil } g.FileName = resp.Name g.length = resp.Size return err } func newGrpcReaderSeeker(userSpacePath string, path string) (*grpcReaderSeeker, error) { g := new(grpcReaderSeeker) g.userSpacePath = userSpacePath g.path = path err := g.initInfo() if err != nil { return nil, err } return g, nil }