implement reader at

This commit is contained in:
Daniel 2020-05-18 05:20:05 +00:00
parent d97c60c346
commit f4a514e81d
3 changed files with 48 additions and 0 deletions

View File

@ -26,6 +26,13 @@ type File interface {
// Read reads up to len(b) bytes from the File. It returns the number of bytes read and any error encountered. At end of file, Read returns 0, io.EOF. // Read reads up to len(b) bytes from the File. It returns the number of bytes read and any error encountered. At end of file, Read returns 0, io.EOF.
Read(p []byte) (int, error) Read(p []byte) (int, error)
// ReadAt implements the ReadAt interface for File
// (reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b).
// At end of file, that error is io.EOF)
ReadAt(p []byte, offset int64) (int, error)
// Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos. // Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos.
// //
// If n > 0, Readdir returns at most n FileInfo structures. In this case, if Readdir returns an empty slice, it will return a non-nil error explaining why. At the end of a directory, the error is io.EOF. // If n > 0, Readdir returns at most n FileInfo structures. In this case, if Readdir returns an empty slice, it will return a non-nil error explaining why. At the end of a directory, the error is io.EOF.

View File

@ -81,6 +81,21 @@ func (f *File) Read(p []byte) (int, error) {
return 0, fmt.Errorf("unable to read %s", f.Name()) return 0, fmt.Errorf("unable to read %s", f.Name())
} }
// ReadAt implements the ReadAt interface for File
// (reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b).
// At end of file, that error is io.EOF)
func (f *File) ReadAt(p []byte, offset int64) (int, error) {
if len(f.data) == 0 || offset >= int64(len(f.data)) {
return 0, io.EOF
}
f.reader = bytes.NewReader(f.data[offset:])
return f.reader.Read(p)
}
// Write writes len(b) bytes to the File. It returns the number of bytes written and an error, if any. Write returns a non-nil error when n != len(b). // Write writes len(b) bytes to the File. It returns the number of bytes written and an error, if any. Write returns a non-nil error when n != len(b).
func (f *File) Write(b []byte) (int, error) { func (f *File) Write(b []byte) (int, error) {
if f.writer == nil { if f.writer == nil {

View File

@ -60,3 +60,29 @@ func Test_File_Seek(t *testing.T) {
r.NotEqual(data, b) r.NotEqual(data, b)
r.Equal([]byte("the arm"), b) r.Equal([]byte("the arm"), b)
} }
func TestFileReadAt(t *testing.T) {
r := require.New(t)
info, err := here.Current()
r.NoError(err)
pkg, err := New(info)
r.NoError(err)
f, err := pkg.Create(":/tolstoy")
r.NoError(err)
data := []byte("pierre always loved natasha")
f.Write(data)
r.NoError(f.Close())
f, err = pkg.Open(":/tolstoy")
r.NoError(err)
b := make([]byte, len(data))
read, err := f.ReadAt(b, 7)
r.NoError(err)
r.Equal("always loved natasha", string(b[:read]))
r.Equal(read, len(data[7:]))
}