mirror of
https://github.com/golang/go
synced 2024-11-23 09:00:04 -07:00
io/fs: add Stat and StatFS
Add Stat helper function, StatFS interface, and test. Add Stat method to fstest.MapFS. Add testing of Stat method to fstest.TestFS. For #41190. Change-Id: Icf8b6eb1c3fa6f93a9be8405ec5a9468fb1da97b Reviewed-on: https://go-review.googlesource.com/c/go/+/243913 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
f098ccf04a
commit
10a1a1a37c
31
src/io/fs/stat.go
Normal file
31
src/io/fs/stat.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fs
|
||||
|
||||
// A StatFS is a file system with a Stat method.
|
||||
type StatFS interface {
|
||||
FS
|
||||
|
||||
// Stat returns a FileInfo describing the file.
|
||||
// If there is an error, it should be of type *PathError.
|
||||
Stat(name string) (FileInfo, error)
|
||||
}
|
||||
|
||||
// Stat returns a FileInfo describing the named file from the file system.
|
||||
//
|
||||
// If fs implements StatFS, Stat calls fs.Stat.
|
||||
// Otherwise, Stat opens the file to stat it.
|
||||
func Stat(fsys FS, name string) (FileInfo, error) {
|
||||
if fsys, ok := fsys.(StatFS); ok {
|
||||
return fsys.Stat(name)
|
||||
}
|
||||
|
||||
file, err := fsys.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
return file.Stat()
|
||||
}
|
36
src/io/fs/stat_test.go
Normal file
36
src/io/fs/stat_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fs_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
. "io/fs"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type statOnly struct{ StatFS }
|
||||
|
||||
func (statOnly) Open(name string) (File, error) { return nil, ErrNotExist }
|
||||
|
||||
func TestStat(t *testing.T) {
|
||||
check := func(desc string, info FileInfo, err error) {
|
||||
t.Helper()
|
||||
if err != nil || info == nil || info.Mode() != 0456 {
|
||||
infoStr := "<nil>"
|
||||
if info != nil {
|
||||
infoStr = fmt.Sprintf("FileInfo(Mode: %#o)", info.Mode())
|
||||
}
|
||||
t.Fatalf("Stat(%s) = %v, %v, want Mode:0456, nil", desc, infoStr, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Stat uses the method when present.
|
||||
info, err := Stat(statOnly{testFsys}, "hello.txt")
|
||||
check("statOnly", info, err)
|
||||
|
||||
// Test that Stat uses Open when the method is not present.
|
||||
info, err = Stat(openOnly{testFsys}, "hello.txt")
|
||||
check("openOnly", info, err)
|
||||
}
|
@ -120,6 +120,10 @@ func (fsys MapFS) ReadFile(name string) ([]byte, error) {
|
||||
return fs.ReadFile(fsOnly{fsys}, name)
|
||||
}
|
||||
|
||||
func (fsys MapFS) Stat(name string) (fs.FileInfo, error) {
|
||||
return fs.Stat(fsOnly{fsys}, name)
|
||||
}
|
||||
|
||||
// A mapFileInfo implements fs.FileInfo and fs.DirEntry for a given map file.
|
||||
type mapFileInfo struct {
|
||||
name string
|
||||
|
@ -230,7 +230,30 @@ func (t *fsTester) checkStat(path string, entry fs.DirEntry) {
|
||||
fentry := formatEntry(entry)
|
||||
finfo := formatInfoEntry(info)
|
||||
if fentry != finfo {
|
||||
t.errorf("%s: mismatch:\n\tentry = %v\n\tfile.Stat() = %v", path, fentry, finfo)
|
||||
t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, finfo)
|
||||
}
|
||||
|
||||
info2, err := fs.Stat(t.fsys, path)
|
||||
if err != nil {
|
||||
t.errorf("%s: fs.Stat: %v", path, err)
|
||||
return
|
||||
}
|
||||
finfo = formatInfo(info)
|
||||
finfo2 := formatInfo(info2)
|
||||
if finfo2 != finfo {
|
||||
t.errorf("%s: fs.Stat(...) = %s\n\twant %s", path, finfo2, finfo)
|
||||
}
|
||||
|
||||
if fsys, ok := t.fsys.(fs.StatFS); ok {
|
||||
info2, err := fsys.Stat(path)
|
||||
if err != nil {
|
||||
t.errorf("%s: fsys.Stat: %v", path, err)
|
||||
return
|
||||
}
|
||||
finfo2 := formatInfo(info2)
|
||||
if finfo2 != finfo {
|
||||
t.errorf("%s: fsys.Stat(...) = %s\n\twant %s", path, finfo2, finfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user