Skip to content

Commit

Permalink
util: add ReadFile function
Browse files Browse the repository at this point in the history
  • Loading branch information
mcuadros committed Apr 28, 2021
1 parent 40a2dbe commit af7e4ac
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
50 changes: 50 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,53 @@ func getUnderlyingAndPath(fs billy.Basic, path string) (billy.Basic, string) {

return u.Underlying(), path
}

// ReadFile reads the named file and returns the contents from the given filesystem.
// A successful call returns err == nil, not err == EOF.
// Because ReadFile reads the whole file, it does not treat an EOF from Read
// as an error to be reported.
func ReadFile(fs billy.Basic, name string) ([]byte, error) {
f, err := fs.Open(name)
if err != nil {
return nil, err
}

defer f.Close()

var size int
if info, err := fs.Stat(name); err == nil {
size64 := info.Size()
if int64(int(size64)) == size64 {
size = int(size64)
}
}

size++ // one byte for final read at EOF
// If a file claims a small size, read at least 512 bytes.
// In particular, files in Linux's /proc claim size 0 but
// then do not work right if read in small pieces,
// so an initial read of 1 byte would not work correctly.

if size < 512 {
size = 512
}

data := make([]byte, 0, size)
for {
if len(data) >= cap(data) {
d := append(data[:cap(data)], 0)
data = d[:len(data)]
}

n, err := f.Read(data[len(data):cap(data)])
data = data[:len(data)+n]

if err != nil {
if err == io.EOF {
err = nil
}

return data, err
}
}
}
21 changes: 21 additions & 0 deletions util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,24 @@ func TestTempDir(t *testing.T) {
}
}
}

func TestReadFile(t *testing.T) {
fs := memfs.New()
f, err := util.TempFile(fs, "", "")
if err != nil {
t.Fatal(err)
}

f.Write([]byte("foo"))
f.Close()

data, err := util.ReadFile(fs, f.Name())
if err != nil {
t.Fatal(err)
}

if string(data) != "foo" || err != nil {
t.Errorf("ReadFile(%q, %q) = %v, %v", fs, f.Name(), data, err)
}

}

0 comments on commit af7e4ac

Please sign in to comment.