2011-06-15 15:06:35 -06:00
|
|
|
// Copyright 2011 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.
|
|
|
|
|
2011-07-14 12:34:53 -06:00
|
|
|
// This file defines types for abstract file system access and
|
|
|
|
// provides an implementation accessing the file system of the
|
|
|
|
// underlying OS.
|
2011-06-15 15:06:35 -06:00
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2011-07-14 12:34:53 -06:00
|
|
|
"fmt"
|
2011-06-15 15:06:35 -06:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
// The FileInfo interface provides access to file information.
|
|
|
|
type FileInfo interface {
|
|
|
|
Name() string
|
|
|
|
Size() int64
|
2011-07-19 09:22:20 -06:00
|
|
|
Mtime_ns() int64
|
2011-06-15 15:06:35 -06:00
|
|
|
IsRegular() bool
|
|
|
|
IsDirectory() bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// The FileSystem interface specifies the methods godoc is using
|
|
|
|
// to access the file system for which it serves documentation.
|
|
|
|
type FileSystem interface {
|
2011-11-01 20:06:05 -06:00
|
|
|
Open(path string) (io.ReadCloser, error)
|
|
|
|
Lstat(path string) (FileInfo, error)
|
|
|
|
Stat(path string) (FileInfo, error)
|
|
|
|
ReadDir(path string) ([]FileInfo, error)
|
2011-09-21 16:12:06 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// ReadFile reads the file named by path from fs and returns the contents.
|
2011-11-01 20:06:05 -06:00
|
|
|
func ReadFile(fs FileSystem, path string) ([]byte, error) {
|
2011-09-21 16:12:06 -06:00
|
|
|
rc, err := fs.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer rc.Close()
|
|
|
|
return ioutil.ReadAll(rc)
|
2011-06-15 15:06:35 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// OS-specific FileSystem implementation
|
|
|
|
|
|
|
|
var OS FileSystem = osFS{}
|
|
|
|
|
|
|
|
// osFI is the OS-specific implementation of FileInfo.
|
|
|
|
type osFI struct {
|
|
|
|
*os.FileInfo
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fi osFI) Name() string {
|
|
|
|
return fi.FileInfo.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fi osFI) Size() int64 {
|
|
|
|
if fi.IsDirectory() {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return fi.FileInfo.Size
|
|
|
|
}
|
|
|
|
|
2011-07-19 09:22:20 -06:00
|
|
|
func (fi osFI) Mtime_ns() int64 {
|
|
|
|
return fi.FileInfo.Mtime_ns
|
|
|
|
}
|
|
|
|
|
2011-06-15 15:06:35 -06:00
|
|
|
// osFS is the OS-specific implementation of FileSystem
|
|
|
|
type osFS struct{}
|
|
|
|
|
2011-11-01 20:06:05 -06:00
|
|
|
func (osFS) Open(path string) (io.ReadCloser, error) {
|
2011-07-14 12:34:53 -06:00
|
|
|
f, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
fi, err := f.Stat()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if fi.IsDirectory() {
|
|
|
|
return nil, fmt.Errorf("Open: %s is a directory", path)
|
|
|
|
}
|
|
|
|
return f, nil
|
2011-06-15 15:06:35 -06:00
|
|
|
}
|
|
|
|
|
2011-11-01 20:06:05 -06:00
|
|
|
func (osFS) Lstat(path string) (FileInfo, error) {
|
2011-06-15 15:06:35 -06:00
|
|
|
fi, err := os.Lstat(path)
|
|
|
|
return osFI{fi}, err
|
|
|
|
}
|
|
|
|
|
2011-11-01 20:06:05 -06:00
|
|
|
func (osFS) Stat(path string) (FileInfo, error) {
|
2011-06-15 15:06:35 -06:00
|
|
|
fi, err := os.Stat(path)
|
|
|
|
return osFI{fi}, err
|
|
|
|
}
|
|
|
|
|
2011-11-01 20:06:05 -06:00
|
|
|
func (osFS) ReadDir(path string) ([]FileInfo, error) {
|
2011-07-14 12:34:53 -06:00
|
|
|
l0, err := ioutil.ReadDir(path) // l0 is sorted
|
2011-06-15 15:06:35 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
l1 := make([]FileInfo, len(l0))
|
|
|
|
for i, e := range l0 {
|
|
|
|
l1[i] = osFI{e}
|
|
|
|
}
|
|
|
|
return l1, nil
|
|
|
|
}
|