Files
2026-08-27 11:00:27 -06:00

308 lines
4.9 KiB
Go

package fileutil
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/alexmullins/zip"
)
func AppendFile(path string, line string) {
file, _ := os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
defer file.Close()
file.WriteString(line + "\n")
}
func Tree(path string, prefix string, isFirstDir ...bool) string {
var sb strings.Builder
files, _ := ioutil.ReadDir(path)
for i, file := range files {
isLast := i == len(files)-1
var pointer string
if isLast {
pointer = prefix + "└── "
} else {
pointer = prefix + "├── "
}
if isFirstDir == nil {
pointer = prefix
}
if file.IsDir() {
fmt.Fprintf(&sb, "%s📂 - %s\n", pointer, file.Name())
if isLast {
sb.WriteString(Tree(filepath.Join(path, file.Name()), prefix+" ", false))
} else {
sb.WriteString(Tree(filepath.Join(path, file.Name()), prefix+"│ ", false))
}
} else {
fmt.Fprintf(&sb, "%s📄 - %s (%.2f kb)\n", pointer, file.Name(), float64(file.Size())/1024)
}
}
tree := sb.String()
if len(tree) > 4090 {
tree = "Too many files to display"
}
return tree
}
func Zip(dirPath string, zipName string) error {
zipFile, err := os.Create(zipName)
if err != nil {
return err
}
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
err = filepath.Walk(dirPath, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
relPath, err := filepath.Rel(dirPath, filePath)
if err != nil {
return err
}
zipEntry, err := zipWriter.Create(relPath)
if err != nil {
return err
}
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(zipEntry, file)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
return nil
}
func ZipWithPassword(dirPath string, zipName string, password string) error {
zipFile, err := os.Create(zipName)
if err != nil {
return err
}
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
err = filepath.Walk(dirPath, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
relPath, err := filepath.Rel(dirPath, filePath)
if err != nil {
return err
}
zipEntry, err := zipWriter.Encrypt(relPath, password)
if err != nil {
return err
}
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(zipEntry, file)
if err != nil {
return err
}
return nil
})
if err != nil {
return err
}
return nil
}
func Copy(src, dst string) (err error) {
file, err := os.Stat(src)
if err != nil {
return err
}
if file.IsDir() {
err = CopyDir(src, dst)
} else {
err = CopyFile(src, dst)
}
return
}
func CopyFile(src, dst string) (err error) {
in, err := os.Open(src)
if err != nil {
return
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return
}
defer func() {
if e := out.Close(); e != nil {
err = e
}
}()
_, err = io.Copy(out, in)
if err != nil {
return
}
err = out.Sync()
if err != nil {
return
}
si, err := os.Stat(src)
if err != nil {
return
}
err = os.Chmod(dst, si.Mode())
if err != nil {
return
}
return
}
func CopyDir(src string, dst string) (err error) {
src = filepath.Clean(src)
dst = filepath.Clean(dst)
si, err := os.Stat(src)
if err != nil {
return err
}
if !si.IsDir() {
return fmt.Errorf("source is not a directory")
}
_, err = os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
return
}
if err == nil {
os.RemoveAll(dst)
}
err = os.MkdirAll(dst, si.Mode())
if err != nil {
return
}
entries, err := ioutil.ReadDir(src)
if err != nil {
return
}
for _, entry := range entries {
srcPath := filepath.Join(src, entry.Name())
dstPath := filepath.Join(dst, entry.Name())
if entry.IsDir() {
err = CopyDir(srcPath, dstPath)
if err != nil {
return
}
} else {
if entry.Mode()&os.ModeSymlink != 0 {
continue
}
err = CopyFile(srcPath, dstPath)
if err != nil {
return
}
}
}
return
}
func IsDir(path string) bool {
fileInfo, err := os.Stat(path)
if err != nil {
return false
}
return fileInfo.IsDir()
}
func Exists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}
func ReadFile(path string) (string, error) {
bytes, err := os.ReadFile(path)
if err != nil {
return "", err
}
return string(bytes), nil
}
func ReadLines(path string) ([]string, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
result := make([]string, 0)
buf := bufio.NewReader(f)
for {
line, _, err := buf.ReadLine()
l := string(line)
if err == io.EOF {
break
}
if err != nil {
continue
}
result = append(result, l)
}
return result, nil
}