You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gophi/core/filesystem.go

111 lines
2.6 KiB
Go

package core
import (
"bytes"
"io"
"os"
"sort"
"github.com/grufwub/go-errors"
)
// OpenFile opens a file for reading (read-only, world-readable)
func OpenFile(p *Path) (*os.File, error) {
file, err := os.OpenFile(p.Absolute(), os.O_RDONLY, 0444)
if err != nil {
return nil, errors.With(err).WrapWithin(ErrFileOpen)
}
return file, nil
}
// StatFile performs a file stat on a file at path
func StatFile(p *Path) (os.FileInfo, error) {
stat, err := os.Stat(p.Absolute())
if err != nil {
return nil, errors.With(err).WrapWithin(ErrFileStat)
}
return stat, nil
}
// ReadFile reads a supplied file descriptor into a return byte slice, or error
func ReadFile(file *os.File) ([]byte, error) {
// Get read buffers, defer putting back
br := fileBufferedReaderPool.Get(file)
defer fileBufferedReaderPool.Put(br)
// Read the file into new file buffer and try return this
buf := &bytes.Buffer{}
_, err := br.WriteTo(buf)
if err != nil {
return nil, errors.With(err).WrapWithin(ErrFileRead)
}
return buf.Bytes(), nil
}
// ScanFile scans a supplied file at file descriptor, using iterator function
func ScanFile(file *os.File, iterator func(string) bool) error {
// Get read buffer, defer putting back
br := fileBufferedReaderPool.Get(file)
defer fileBufferedReaderPool.Put(br)
// Iterate through file!
for {
// Read a line
line, err := br.ReadString('\n')
if err != nil {
if err == io.EOF {
// Reached end of file, perform final iteration
// and break-out. Will not have hit delim
iterator(line)
break
} else {
// Bad error, return
return errors.With(err).WrapWithin(ErrFileRead)
}
}
// Run scan iterator on this line, breaking out if requested,
// skipping final byte which is '\n'
if !iterator(line[:len(line)-1]) {
break
}
}
// Return no errors :)
return nil
}
// ScanDirectory reads the contents of a directory and performs the iterator function on each os.FileInfo entry returned
func ScanDirectory(dir *os.File, p *Path, iterator func(os.FileInfo, *Path)) error {
nameList, err := dir.Readdirnames(-1)
if err != nil {
return errors.With(err).WrapWithin(ErrDirectoryRead)
}
// Sort by name
sort.Strings(nameList)
// Walk through the directory list using supplied iterator function
for _, name := range nameList {
// Make new Path object
fp := p.JoinPathUnsafe(name)
// Skip restricted files
if IsRestrictedPath(fp) || IsHiddenPath(fp) {
continue
}
// Get stat or continue
stat, err := StatFile(fp)
if err != nil {
SystemLog.Error("Error during dir scan:", err.Error())
continue
}
// Perform iterator
iterator(stat, fp)
}
return nil
}