Initial QSfera import
This commit is contained in:
+201
@@ -0,0 +1,201 @@
|
||||
package fsutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/gookit/goutil/x/basefn"
|
||||
)
|
||||
|
||||
// ************************************************************
|
||||
// temp file or dir
|
||||
// ************************************************************
|
||||
|
||||
// OSTempFile create a temp file on os.TempDir()
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// fsutil.OSTempFile("example.*.txt")
|
||||
func OSTempFile(pattern string) (*os.File, error) {
|
||||
return os.CreateTemp(os.TempDir(), pattern)
|
||||
}
|
||||
|
||||
// TempFile is like os.CreateTemp, but can custom temp dir.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// // create temp file on os.TempDir()
|
||||
// fsutil.TempFile("", "example.*.txt")
|
||||
// // create temp file on "testdata" dir
|
||||
// fsutil.TempFile("testdata", "example.*.txt")
|
||||
func TempFile(dir, pattern string) (*os.File, error) {
|
||||
return os.CreateTemp(dir, pattern)
|
||||
}
|
||||
|
||||
// OSTempDir creates a new temp dir on os.TempDir and return the temp dir path
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// fsutil.OSTempDir("example.*")
|
||||
func OSTempDir(pattern string) (string, error) {
|
||||
return os.MkdirTemp(os.TempDir(), pattern)
|
||||
}
|
||||
|
||||
// TempDir creates a new temp dir and return the temp dir path
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// fsutil.TempDir("", "example.*")
|
||||
// fsutil.TempDir("testdata", "example.*")
|
||||
func TempDir(dir, pattern string) (string, error) {
|
||||
return os.MkdirTemp(dir, pattern)
|
||||
}
|
||||
|
||||
// ************************************************************
|
||||
// write, copy files
|
||||
// ************************************************************
|
||||
|
||||
// MustSave create file and write contents to file, panic on error.
|
||||
//
|
||||
// - data type allow: string, []byte, io.Reader
|
||||
//
|
||||
// default option see NewOpenOption()
|
||||
func MustSave(filePath string, data any, optFns ...OpenOptionFunc) {
|
||||
basefn.MustOK(SaveFile(filePath, data, optFns...))
|
||||
}
|
||||
|
||||
// SaveFile create file and write contents to file. will auto create dir.
|
||||
//
|
||||
// - data type allow: string, []byte, io.Reader
|
||||
//
|
||||
// default option see NewOpenOption()
|
||||
func SaveFile(filePath string, data any, optFns ...OpenOptionFunc) error {
|
||||
opt := NewOpenOption(optFns...)
|
||||
return WriteFile(filePath, data, opt.Perm, opt.Flag)
|
||||
}
|
||||
|
||||
// WriteData Quick write any data to file, alias of PutContents
|
||||
func WriteData(filePath string, data any, fileFlag ...int) (int, error) {
|
||||
return PutContents(filePath, data, fileFlag...)
|
||||
}
|
||||
|
||||
// PutContents create file and write contents to file at once. Will auto create dir
|
||||
//
|
||||
// data type allows: string, []byte, io.Reader
|
||||
//
|
||||
// Tip: file flag default is FsCWTFlags (override write)
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// fsutil.PutContents(filePath, contents, fsutil.FsCWAFlags) // append write
|
||||
// fsutil.Must2(fsutil.PutContents(filePath, contents)) // panic on error
|
||||
func PutContents(filePath string, data any, fileFlag ...int) (int, error) {
|
||||
f, err := QuickOpenFile(filePath, basefn.FirstOr(fileFlag, FsCWTFlags))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return WriteOSFile(f, data)
|
||||
}
|
||||
|
||||
// WriteFile create file and write contents to file, can set perm for a file.
|
||||
//
|
||||
// data type allows: string, []byte, io.Reader
|
||||
//
|
||||
// Tip: file flag default is FsCWTFlags (override write)
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// fsutil.WriteFile(filePath, contents, fsutil.DefaultFilePerm, fsutil.FsCWAFlags)
|
||||
func WriteFile(filePath string, data any, perm os.FileMode, fileFlag ...int) error {
|
||||
flag := basefn.FirstOr(fileFlag, FsCWTFlags)
|
||||
f, err := OpenFile(filePath, flag, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = WriteOSFile(f, data)
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteOSFile write data to give os.File, then close file.
|
||||
//
|
||||
// data type allows: string, []byte, io.Reader
|
||||
func WriteOSFile(f *os.File, data any) (n int, err error) {
|
||||
switch typData := data.(type) {
|
||||
case []byte:
|
||||
n, err = f.Write(typData)
|
||||
case string:
|
||||
n, err = f.WriteString(typData)
|
||||
case io.Reader: // eg: buffer
|
||||
var n64 int64
|
||||
n64, err = io.Copy(f, typData)
|
||||
n = int(n64)
|
||||
default:
|
||||
_ = f.Close()
|
||||
panic("WriteFile: data type only allow: []byte, string, io.Reader")
|
||||
}
|
||||
|
||||
if err1 := f.Close(); err1 != nil && err == nil {
|
||||
err = err1
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// CopyFile copy a file to another file path.
|
||||
func CopyFile(srcPath, dstPath string) error {
|
||||
srcFile, err := os.OpenFile(srcPath, FsRFlags, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
// create and open file
|
||||
dstFile, err := QuickOpenFile(dstPath, FsCWTFlags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstFile.Close()
|
||||
|
||||
_, err = io.Copy(dstFile, srcFile)
|
||||
return err
|
||||
}
|
||||
|
||||
// MustCopyFile copy file to another path.
|
||||
func MustCopyFile(srcPath, dstPath string) {
|
||||
err := CopyFile(srcPath, dstPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateContents read file contents, call handleFn(contents) handle, then write updated contents to file
|
||||
func UpdateContents(filePath string, handleFn func(bs []byte) []byte) error {
|
||||
osFile, err := os.OpenFile(filePath, os.O_RDWR|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer osFile.Close()
|
||||
|
||||
// read file contents
|
||||
if bs, err1 := io.ReadAll(osFile); err1 == nil {
|
||||
bs = handleFn(bs)
|
||||
_, err = osFile.Write(bs)
|
||||
} else {
|
||||
err = err1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateSymlink creates a symbolic link
|
||||
func CreateSymlink(target, linkPath string) error {
|
||||
// Check if the link already exists
|
||||
if IsFile(linkPath) {
|
||||
// Remove existing link/file
|
||||
if err := os.Remove(linkPath); err != nil {
|
||||
return fmt.Errorf("failed to remove existing symlink: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return os.Symlink(target, linkPath)
|
||||
}
|
||||
Reference in New Issue
Block a user