diff --git a/mem/file.go b/mem/file.go index 62fe4498..829c658b 100644 --- a/mem/file.go +++ b/mem/file.go @@ -201,33 +201,30 @@ func (f *File) ReadDir(n int) ([]fs.DirEntry, error) { return di, nil } -func (f *File) Read(b []byte) (n int, err error) { +func (f *File) ReadAt(b []byte, off int64) (n int, err error) { f.fileData.Lock() defer f.fileData.Unlock() if f.closed { return 0, ErrFileClosed } - if len(b) > 0 && int(f.at) == len(f.fileData.data) { + if len(b) > 0 && int(off) == len(f.fileData.data) { return 0, io.EOF } - if int(f.at) > len(f.fileData.data) { + if int(off) > len(f.fileData.data) { return 0, io.ErrUnexpectedEOF } - if len(f.fileData.data)-int(f.at) >= len(b) { + if len(f.fileData.data)-int(off) >= len(b) { n = len(b) } else { - n = len(f.fileData.data) - int(f.at) + n = len(f.fileData.data) - int(off) } - copy(b, f.fileData.data[f.at:f.at+int64(n)]) - atomic.AddInt64(&f.at, int64(n)) + copy(b, f.fileData.data[off:off+int64(n)]) return } -func (f *File) ReadAt(b []byte, off int64) (n int, err error) { - prev := atomic.LoadInt64(&f.at) - atomic.StoreInt64(&f.at, off) - n, err = f.Read(b) - atomic.StoreInt64(&f.at, prev) +func (f *File) Read(b []byte) (n int, err error) { + n, err = f.ReadAt(b, atomic.LoadInt64(&f.at)) + atomic.AddInt64(&f.at, int64(n)) return } @@ -268,7 +265,7 @@ func (f *File) Seek(offset int64, whence int) (int64, error) { return f.at, nil } -func (f *File) Write(b []byte) (n int, err error) { +func (f *File) WriteAt(b []byte, off int64) (n int, err error) { if f.closed { return 0, ErrFileClosed } @@ -276,30 +273,28 @@ func (f *File) Write(b []byte) (n int, err error) { return 0, &os.PathError{Op: "write", Path: f.fileData.name, Err: errors.New("file handle is read only")} } n = len(b) - cur := atomic.LoadInt64(&f.at) f.fileData.Lock() defer f.fileData.Unlock() - diff := cur - int64(len(f.fileData.data)) + diff := off - int64(len(f.fileData.data)) var tail []byte - if n+int(cur) < len(f.fileData.data) { - tail = f.fileData.data[n+int(cur):] + if n+int(off) < len(f.fileData.data) { + tail = f.fileData.data[n+int(off):] } if diff > 0 { f.fileData.data = append(f.fileData.data, append(bytes.Repeat([]byte{0o0}, int(diff)), b...)...) f.fileData.data = append(f.fileData.data, tail...) } else { - f.fileData.data = append(f.fileData.data[:cur], b...) + f.fileData.data = append(f.fileData.data[:off], b...) f.fileData.data = append(f.fileData.data, tail...) } setModTime(f.fileData, time.Now()) - - atomic.AddInt64(&f.at, int64(n)) return } -func (f *File) WriteAt(b []byte, off int64) (n int, err error) { - atomic.StoreInt64(&f.at, off) - return f.Write(b) +func (f *File) Write(b []byte) (n int, err error) { + n, err = f.WriteAt(b, atomic.LoadInt64(&f.at)) + atomic.AddInt64(&f.at, int64(n)) + return } func (f *File) WriteString(s string) (ret int, err error) {