iohelper/iohelper.go (82 lines of code) (raw):

package iohelper /* * This file contains generic file/directory manipulation functions that use * the function pointers and types from the operating package, for easier test * mocking around file IO. */ import ( "bufio" "io" "os" "github.com/cloudberrydb/gp-common-go-libs/gplog" "github.com/cloudberrydb/gp-common-go-libs/operating" "github.com/pkg/errors" ) /* * The following six OpenFileFor... and MustOpenFileFor... functions abstract * the most common cases for wanting to open files: when reading, open a read- * only handle and ignore file permissions as long as it's readable, and when * writing or appending, create the file if it doesn't exist with relatively * standard 644 permissions and then open it. * * If more niche or complex scenarios are involved, the underlying OpenFileRead * and OpenFileWrite functions should be used directly, to grant more fine- * grained control over flags and permissions. */ func OpenFileForReading(filename string) (operating.ReadCloserAt, error) { fileHandle, err := operating.System.OpenFileRead(filename, os.O_RDONLY, 0644) if err != nil { return nil, errors.Errorf("Unable to open file for reading: %s", err) } return fileHandle, nil } func MustOpenFileForReading(filename string) operating.ReadCloserAt { fileHandle, err := OpenFileForReading(filename) gplog.FatalOnError(err) return fileHandle } func OpenFileForWriting(filename string) (io.WriteCloser, error) { flags := os.O_CREATE | os.O_WRONLY | os.O_TRUNC fileHandle, err := operating.System.OpenFileWrite(filename, flags, 0644) if err != nil { return nil, errors.Errorf("Unable to create or open file for writing: %s", err) } return fileHandle, nil } func MustOpenFileForWriting(filename string) io.WriteCloser { fileHandle, err := OpenFileForWriting(filename) gplog.FatalOnError(err) return fileHandle } func OpenFileForAppending(filename string) (io.WriteCloser, error) { flags := os.O_APPEND | os.O_CREATE | os.O_WRONLY fileHandle, err := operating.System.OpenFileWrite(filename, flags, 0644) if err != nil { return nil, errors.Errorf("Unable to create or open file for appending: %s", err) } return fileHandle, nil } func MustOpenFileForAppending(filename string) io.WriteCloser { fileHandle, err := OpenFileForAppending(filename) gplog.FatalOnError(err) return fileHandle } func FileExistsAndIsReadable(filename string) bool { _, err := operating.System.Stat(filename) if err == nil { var fileHandle io.ReadCloser fileHandle, err = OpenFileForReading(filename) if fileHandle != nil { _ = fileHandle.Close() } if err == nil { return true } } return false } func ReadLinesFromFile(filename string) ([]string, error) { fileHandle, err := OpenFileForReading(filename) if err != nil { return nil, err } contents := make([]string, 0) scanner := bufio.NewScanner(fileHandle) for scanner.Scan() { contents = append(contents, scanner.Text()) } err = fileHandle.Close() if err != nil { return nil, err } return contents, nil } func MustReadLinesFromFile(filename string) []string { contents, err := ReadLinesFromFile(filename) gplog.FatalOnError(err) return contents }