diff options
| -rw-r--r-- | file.go | 24 | ||||
| -rw-r--r-- | fs.go | 19 | ||||
| -rw-r--r-- | fs_test.go | 13 |
3 files changed, 48 insertions, 8 deletions
@@ -1,21 +1,29 @@ package s3 import ( + "context" + "io" "os" + "path" ) type File struct { - name string + fs *Fs + key string + r io.ReadCloser + w io.WriteCloser + cancel context.CancelFunc } // implements io.Closer func (f *File) Close() error { - panic("not implemented") + f.cancel() + return nil } // implements io.Reader func (f *File) Read(b []byte) (int, error) { - panic("not implemented") + return f.r.Read(b) } // implements io.ReaderAt @@ -25,7 +33,7 @@ func (f *File) ReadAt(p []byte, off int64) (int, error) { // implements io.Writer func (f *File) Write(p []byte) (int, error) { - panic("not implemented") + return f.w.Write(p) } // implements io.WriterAt @@ -34,7 +42,7 @@ func (f *File) WriteAt(p []byte, off int64) (int, error) { } func (f *File) Name() string { - return f.name + return path.Base(f.key) } func (f *File) Readdir(count int) ([]os.FileInfo, error) { @@ -45,10 +53,14 @@ func (f *File) Readdirnames(n int) ([]string, error) { panic("not implemented") } -func (f *File) Stat() (os.FileInfo, error) { +func (f *File) Seek(offset int64, whence int) (int64, error) { panic("not implemented") } +func (f *File) Stat() (os.FileInfo, error) { + return f.fs.Stat(f.key) +} + func (f *File) Sync() error { panic("not implemented") } @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "io" neturl "net/url" "os" "strings" @@ -91,8 +92,13 @@ func (fs *Fs) MkdirAll(path string, perm os.FileMode) error { } // Open opens a file, returning it or an error, if any happens. -func (fs *Fs) Open(name string) (File, error) { - panic("not implemented") +func (fs *Fs) Open(name string) (afero.File, error) { + ctx, cancel := fs.contextWithTimeout() + obj, err := fs.client.GetObject(ctx, fs.bucket, name, minio.GetObjectOptions{}) + if err != nil { + return nil, err + } + return fs.newObjectReader(name, obj, cancel), nil } // OpenFile opens a file using the given flags and the given mode. @@ -181,6 +187,15 @@ func (fs *Fs) contextWithTimeout() (context.Context, context.CancelFunc) { return context.WithTimeout(context.Background(), fs.Timeout) } +func (fs *Fs) newObjectReader(key string, r io.ReadCloser, cancel context.CancelFunc) *File { + return &File{ + fs: fs, + key: key, + r: r, + cancel: cancel, + } +} + func transformError(err error) error { resp, ok := err.(minio.ErrorResponse) if !ok { @@ -1,6 +1,7 @@ package s3 import ( + "io" "testing" "time" @@ -75,6 +76,18 @@ func TestFsStatNoExist(t *testing.T) { is.Equal(err, afero.ErrFileNotFound) } +func TestFsOpenRead(t *testing.T) { + is := is.New(t) + fs, err := newTestFs() + is.NoErr(err) + f, err := fs.Open("dir/file") + is.NoErr(err) + defer f.Close() + b, err := io.ReadAll(f) + is.NoErr(err) + is.Equal(b, []byte("test")) +} + func newTestFs() (*Fs, error) { fs, err := NewFsFromURL("http://testuser:[email protected]:9000/test-bucket") return fs, err |
