mirror of
https://github.com/rjNemo/go-microservices-tuto
synced 2026-06-06 02:16:46 +00:00
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package files
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
// Local is an implementation of the Storage interface which works with the
|
|
// local disk on the current machine
|
|
type Local struct {
|
|
maxFileSize int // maximum numbber of bytes for files
|
|
basePath string
|
|
}
|
|
|
|
// NewLocal creates a new Local filesytem with the given base path
|
|
// basePath is the base directory to save files to
|
|
// maxSize is the max number of bytes that a file can be
|
|
func NewLocal(basePath string, maxSize int) (*Local, error) {
|
|
p, err := filepath.Abs(basePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Local{basePath: p}, nil
|
|
}
|
|
|
|
// Save the contents of the Writer to the given path
|
|
// path is a relative path, basePath will be appended
|
|
func (l *Local) Save(path string, contents io.Reader) error {
|
|
// get the full path for the file
|
|
fp := l.fullPath(path)
|
|
|
|
// get the directory and make sure it exists
|
|
d := filepath.Dir(fp)
|
|
err := os.MkdirAll(d, os.ModePerm)
|
|
if err != nil {
|
|
return xerrors.Errorf("Unable to create directory: %w", err)
|
|
}
|
|
|
|
// if the file exists delete it
|
|
_, err = os.Stat(fp)
|
|
if err == nil {
|
|
err = os.Remove(fp)
|
|
if err != nil {
|
|
return xerrors.Errorf("Unable to delete file: %w", err)
|
|
}
|
|
} else if !os.IsNotExist(err) {
|
|
// if this is anything other than a not exists error
|
|
return xerrors.Errorf("Unable to get file info: %w", err)
|
|
}
|
|
|
|
// create a new file at the path
|
|
f, err := os.Create(fp)
|
|
if err != nil {
|
|
return xerrors.Errorf("Unable to create file: %w", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
// write the contents to the new file
|
|
// ensure that we are not writing greater than max bytes
|
|
_, err = io.Copy(f, contents)
|
|
if err != nil {
|
|
return xerrors.Errorf("Unable to write to file: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Get the file at the given path and return a Reader
|
|
// the calling function is responsible for closing the reader
|
|
func (l *Local) Get(path string) (*os.File, error) {
|
|
// get the full path for the file
|
|
fp := l.fullPath(path)
|
|
|
|
// open the file
|
|
f, err := os.Open(fp)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("Unable to open file: %w", err)
|
|
}
|
|
|
|
return f, nil
|
|
}
|
|
|
|
// returns the absolute path
|
|
func (l *Local) fullPath(path string) string {
|
|
// append the given path to the base path
|
|
return filepath.Join(l.basePath, path)
|
|
}
|