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.
ntool/nfs/oper.go

256 lines
6.4 KiB
Go

package nfs
import (
"archive/zip"
"fmt"
"git.noahlan.cn/noahlan/ntool/ngo"
"io"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
)
// Mkdir alias of os.MkdirAll()
func Mkdir(dirPath string, perm os.FileMode) error {
return os.MkdirAll(dirPath, perm)
}
// MkDirs batch make multi dirs at once
func MkDirs(perm os.FileMode, dirPaths ...string) error {
for _, dirPath := range dirPaths {
if err := os.MkdirAll(dirPath, perm); err != nil {
return err
}
}
return nil
}
// MkSubDirs batch make multi sub-dirs at once
func MkSubDirs(perm os.FileMode, parentDir string, subDirs ...string) error {
for _, dirName := range subDirs {
dirPath := parentDir + "/" + dirName
if err := os.MkdirAll(dirPath, perm); err != nil {
return err
}
}
return nil
}
// MkParentDir quick create parent dir
func MkParentDir(fpath string) error {
dirPath := filepath.Dir(fpath)
if !IsDir(dirPath) {
return os.MkdirAll(dirPath, 0775)
}
return nil
}
// ************************************************************
// open/create files
// ************************************************************
// some commonly flag const for open file
const (
FsCWAFlags = os.O_CREATE | os.O_WRONLY | os.O_APPEND // create, append write-only
FsCWTFlags = os.O_CREATE | os.O_WRONLY | os.O_TRUNC // create, override write-only
FsCWFlags = os.O_CREATE | os.O_WRONLY // create, write-only
FsRFlags = os.O_RDONLY // read-only
)
// OpenFile like os.OpenFile, but will auto create dir.
//
// Usage:
//
// file, err := OpenFile("path/to/file.txt", FsCWFlags, 0666)
func OpenFile(filepath string, flag int, perm os.FileMode) (*os.File, error) {
fileDir := path.Dir(filepath)
if err := os.MkdirAll(fileDir, DefaultDirPerm); err != nil {
return nil, err
}
file, err := os.OpenFile(filepath, flag, perm)
if err != nil {
return nil, err
}
return file, nil
}
// MustOpenFile like os.OpenFile, but will auto create dir.
//
// Usage:
//
// file := MustOpenFile("path/to/file.txt", FsCWFlags, 0666)
func MustOpenFile(filepath string, flag int, perm os.FileMode) *os.File {
file, err := OpenFile(filepath, flag, perm)
if err != nil {
panic(err)
}
return file
}
// QuickOpenFile like os.OpenFile, open for append write. if not exists, will create it.
//
// Alias of OpenAppendFile()
func QuickOpenFile(filepath string, fileFlag ...int) (*os.File, error) {
flag := ngo.FirstOr(fileFlag, FsCWAFlags)
return OpenFile(filepath, flag, DefaultFilePerm)
}
// OpenAppendFile like os.OpenFile, open for append write. if not exists, will create it.
func OpenAppendFile(filepath string, filePerm ...os.FileMode) (*os.File, error) {
perm := ngo.FirstOr(filePerm, DefaultFilePerm)
return OpenFile(filepath, FsCWAFlags, perm)
}
// OpenTruncFile like os.OpenFile, open for override write. if not exists, will create it.
func OpenTruncFile(filepath string, filePerm ...os.FileMode) (*os.File, error) {
perm := ngo.FirstOr(filePerm, DefaultFilePerm)
return OpenFile(filepath, FsCWTFlags, perm)
}
// OpenReadFile like os.OpenFile, open file for read contents
func OpenReadFile(filepath string) (*os.File, error) {
return os.OpenFile(filepath, FsRFlags, OnlyReadFilePerm)
}
// CreateFile create file if not exists
//
// Usage:
//
// CreateFile("path/to/file.txt", 0664, 0666)
func CreateFile(fpath string, filePerm, dirPerm os.FileMode, fileFlag ...int) (*os.File, error) {
dirPath := path.Dir(fpath)
if !IsDir(dirPath) {
err := os.MkdirAll(dirPath, dirPerm)
if err != nil {
return nil, err
}
}
flag := ngo.FirstOr(fileFlag, FsCWAFlags)
return os.OpenFile(fpath, flag, filePerm)
}
// MustCreateFile create file, will panic on error
func MustCreateFile(filePath string, filePerm, dirPerm os.FileMode) *os.File {
file, err := CreateFile(filePath, filePerm, dirPerm)
if err != nil {
panic(err)
}
return file
}
// ************************************************************
// remove files
// ************************************************************
// Remove removes the named file or (empty) directory.
func Remove(fPath string) error {
return os.Remove(fPath)
}
// MustRemove removes the named file or (empty) directory.
// NOTICE: will panic on error
func MustRemove(fPath string) {
if err := os.Remove(fPath); err != nil {
panic(err)
}
}
// QuietRemove removes the named file or (empty) directory.
//
// NOTICE: will ignore error
func QuietRemove(fPath string) { _ = os.Remove(fPath) }
// RmIfExist removes the named file or (empty) directory on exists.
func RmIfExist(fPath string) error { return DeleteIfExist(fPath) }
// DeleteIfExist removes the named file or (empty) directory on exists.
func DeleteIfExist(fPath string) error {
if PathExists(fPath) {
return os.Remove(fPath)
}
return nil
}
// RmFileIfExist removes the named file on exists.
func RmFileIfExist(fPath string) error { return DeleteIfFileExist(fPath) }
// DeleteIfFileExist removes the named file on exists.
func DeleteIfFileExist(fPath string) error {
if IsFile(fPath) {
return os.Remove(fPath)
}
return nil
}
// RemoveSub removes all sub files and dirs of dirPath, but not remove dirPath.
func RemoveSub(dirPath string, fns ...FilterFunc) error {
return FindInDir(dirPath, func(fPath string, ent fs.DirEntry) error {
if ent.IsDir() {
if err := RemoveSub(fPath, fns...); err != nil {
return err
}
}
return os.Remove(fPath)
}, fns...)
}
// ************************************************************
// other operates
// ************************************************************
// Unzip a zip archive
// from https://blog.csdn.net/wangshubo1989/article/details/71743374
func Unzip(archive, targetDir string) (err error) {
reader, err := zip.OpenReader(archive)
if err != nil {
return err
}
if err = os.MkdirAll(targetDir, DefaultDirPerm); err != nil {
return
}
for _, file := range reader.File {
if strings.Contains(file.Name, "..") {
return fmt.Errorf("illegal file path in zip: %v", file.Name)
}
fullPath := filepath.Join(targetDir, file.Name)
if file.FileInfo().IsDir() {
err = os.MkdirAll(fullPath, file.Mode())
if err != nil {
return err
}
continue
}
fileReader, err := file.Open()
if err != nil {
return err
}
targetFile, err := os.OpenFile(fullPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
_ = fileReader.Close()
return err
}
_, err = io.Copy(targetFile, fileReader)
// close all
_ = fileReader.Close()
targetFile.Close()
if err != nil {
return err
}
}
return
}