Files
WddSuperAgent/agent-wdd/utils/FileUtils.go

503 lines
14 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package utils
import (
"agent-wdd/log"
"bufio"
"fmt"
"io"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
)
// AppendFileToFile 将源文件的内容添加到目标文件
func AppendFileToFile(sourceFile, targetFile string) bool {
// 打开源文件
source, err := os.Open(sourceFile)
if err != nil {
log.Error("[BasicAppendSourceToFile] - error open source file => %s, error is %s", sourceFile, err.Error())
return false
}
defer source.Close()
// 打开目标文件,如果不存在则创建,如果存在则在末尾追加
target, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Error("[BasicAppendSourceToFile] - error open target file => %s, error is %s", sourceFile, err.Error())
return false
}
defer target.Close()
// 将源文件内容复制到目标文件
_, err = io.Copy(target, source)
if err != nil {
log.Error("[BasicAppendSourceToFile] - Error appending to target file: %s", err.Error())
return false
}
return true
}
// AppendOverwriteContentToFile 向目标文件中写入一些内容,覆盖源文件
func AppendOverwriteContentToFile(content string, targetFile string) bool {
err := os.Remove(targetFile)
if err != nil {
log.Warning("[BasicAppendOverwriteContentToFile] - Error removing file: %s , error is %s", targetFile, err.Error())
}
return AppendContentToFile(content, targetFile)
}
// AppendContentToFile 向目标文件(targetFile 文件的绝对路径)中追加写入一些内容, 如果文件不存在,那么就创建相应的目录及文件
func AppendContentToFile(content string, targetFile string) bool {
// 创建目标文件的目录(递归创建)
dir := filepath.Dir(targetFile)
if err := os.MkdirAll(dir, 0755); err != nil {
return false
}
// 打开文件用于追加。如果文件不存在,将会创建一个新文件。
file, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Error("[BasicAppendContentToFile] - Error opening file: %s , error is %s", targetFile, err.Error())
return false
}
defer file.Close() // 确保文件最终被关闭
// 写入内容到文件
// 内容非空时执行写入操作
if content != "" {
if _, err := file.WriteString(content); err != nil {
log.Error("[BasicAppendContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
return false
}
}
return true
}
// AppendOverwriteListContentToFile 将一个字符串列表中的内容,一行一行的写入文件中
func AppendOverwriteListContentToFile(contentList []string, targetFile string) bool {
err := os.Remove(targetFile)
if err != nil {
log.Warning("[AppendOverwriteListContentToFile] - Error removing file: %s , error is %s", targetFile, err.Error())
}
// 打开文件用于追加。如果文件不存在,将会创建一个新文件。
file, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Error("[AppendOverwriteListContentToFile] - Error opening file: %s , error is %s", targetFile, err.Error())
return false
}
defer file.Close() // 确保文件最终被关闭
// 写入内容到文件
for _, contentLine := range contentList {
//bytes, _ := json.Marshal(contentLine)
if _, err := file.WriteString(contentLine + "\n"); err != nil {
log.Error("[AppendOverwriteListContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
return false
}
}
return true
}
// AppendK8sYamlWithSplitLineToFile 专门为k8s的yaml文件设计的在每次写入内容之前先写入一行分隔符
func AppendK8sYamlWithSplitLineToFile(content string, targetFile string) bool {
// 打开文件用于追加。如果文件不存在,将会创建一个新文件。
file, err := os.OpenFile(targetFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Error("[BasicAppendContentToFile] - Error opening file: %s , error is %s", targetFile, err.Error())
return false
}
defer file.Close() // 确保文件最终被关闭
// 写入内容到文件
if _, err := file.WriteString("---"); err != nil {
log.Error("[BasicAppendContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
return false
}
if _, err := file.WriteString(content); err != nil {
log.Error("[BasicAppendContentToFile] - Error writing to file: %s , error is %s", targetFile, err.Error())
return false
}
return true
}
// AppendNullOverWriteToFile 清空一个文件
func AppendNullOverWriteToFile(targetFile string) bool {
// 使用os.O_TRUNC清空文件内容
file, err := os.OpenFile(targetFile, os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil {
log.Error("[AppendNullOverWriteToFile] - Error opening file: %s, error is %s", targetFile, err.Error())
return false
}
defer file.Close() // 确保在函数退出前关闭文件
return true
}
func WordSpaceCompletion(source string, totalLength int) string {
sourceLength := len(source)
if sourceLength >= totalLength {
return source
}
for i := 0; i < totalLength-sourceLength; i++ {
source += " "
}
return source
}
// IsDirOrFile 如果是目录则返回true是文件则返回false
func IsDirOrFile(path string) bool {
info, err := os.Stat(path)
if err != nil {
return false
}
return info.IsDir()
}
// FileExists 文件存在返回true不存在返回false如果文件是一个目录也返回false
func FileExists(fileFullPath string) bool {
info, err := os.Stat(fileFullPath)
if err != nil {
return false
}
return !info.IsDir()
}
// CreateFolder 创建文件夹如果文件夹存在则返回true否则返回false
func CreateFolder(folderName string) bool {
// 递归创建 类似于 mkdir -p folderName
if _, err := os.Stat(folderName); os.IsNotExist(err) {
return os.MkdirAll(folderName, 0755) == nil
}
return true
}
// FileOrFolderExists 文件或者目录是否返回true不存在返回false
func FileOrFolderExists(fileFullPath string) bool {
_, err := os.Stat(fileFullPath)
return !os.IsNotExist(err)
}
// FileExistAndNotNull 文件不为空返回true 文件为空返回false
func FileExistAndNotNull(filename string) bool {
// Check if the file exists
if _, err := os.Stat(filename); os.IsNotExist(err) {
log.Debug("文件 %s 不存在!", filename)
return false
}
// Open the file for reading
file, err := os.Open(filename)
defer file.Close()
if err != nil {
log.Debug("文件 %s 打开有误!", filename)
return false // Handle error according to your needs
}
// Get the file size
info, _ := file.Stat()
size := info.Size()
// Check if the file is not empty
return size > 0
}
// ListAllFileInFolder 列出一个目录中的所有文件返回文件名忽略folder不带全路径
func ListAllFileInFolder(folderName string) ([]string, error) {
return listAllFileInFolderWithFullPath(folderName, false)
}
func ListAllFileInFolderWithFullPath(folderName string) ([]string, error) {
return listAllFileInFolderWithFullPath(folderName, true)
}
func listAllFileInFolderWithFullPath(folderName string, fullPath bool) ([]string, error) {
files := make([]string, 0)
err := filepath.Walk(folderName, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
if fullPath {
files = append(files, path)
} else {
files = append(files, info.Name())
}
}
return nil
})
if err != nil {
return nil, err
}
return files, nil
}
// RemoveFile 删除文件如果文件不存在则返回true
func RemoveFile(filePath string) bool {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
log.Error("文件不存在: %s", filePath)
return true
}
err := os.Remove(filePath)
if err != nil {
log.Error("Failed to remove file: %s", err.Error())
return false
}
return true
}
func RemoveFolderComplete(folderName string) bool {
err := filepath.Walk(folderName,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
return os.Remove(path)
}
return nil
})
if err != nil {
return false
}
err = os.RemoveAll(folderName)
if err != nil {
return false
}
return true
}
func ReadAllContentFromFile(fileFullPath string) (result []string) {
f, err := os.Open(fileFullPath)
if err != nil {
fmt.Println(err)
return result
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if len(line) > 0 { // ignore empty lines
result = append(result, line)
}
}
if err := scanner.Err(); err != nil {
fmt.Println(err)
return result
}
return result
}
// FindContentInFile 在文件中查找内容如果存在则返回true否则返回false 类似于grep -q content targetFile
func FindContentInFile(content string, targetFile string) bool {
// 读取文件内容
fileContent, err := os.ReadFile(targetFile)
if err != nil {
log.Error("[FindContentInFile] - Error reading file: %s , error is %s", targetFile, err.Error())
return false
}
// 将文件内容按行分割
lines := strings.Split(string(fileContent), "\n")
// 遍历每一行
for _, line := range lines {
if strings.Contains(line, content) {
return true
}
}
return false
}
// FindAndReplaceContentInFile 在文件中查找内容,如果存在,则替换,如果存在多个,则替换全部 类似于sed -i 's/oldContent/newContent/g' targetFile
func FindAndReplaceContentInFile(oldContent string, newContent string, targetFile string) bool {
// 读取文件内容
fileContent, err := os.ReadFile(targetFile)
if err != nil {
log.Error("[FindAndReplaceContentInFile] - Error reading file: %s , error is %s", targetFile, err.Error())
return false
}
// 将文件内容按行分割
lines := strings.Split(string(fileContent), "\n")
// 遍历每一行
for i, line := range lines {
if strings.Contains(line, oldContent) {
lines[i] = strings.Replace(line, oldContent, newContent, -1)
}
}
// 将修改后的内容写回文件
err = os.WriteFile(targetFile, []byte(strings.Join(lines, "\n")), 0644)
if err != nil {
log.Error("[FindAndReplaceContentInFile] - Error writing file: %s , error is %s", targetFile, err.Error())
return false
}
return true
}
// FindAndDeleteContentInFile 在文件中查找内容,如果存在,则删除,如果存在多个,则删除全部 类似于sed -i '/content/d' targetFile
func FindAndDeleteContentInFile(content string, targetFile string) bool {
// 读取文件内容
fileContent, err := os.ReadFile(targetFile)
if err != nil {
log.Error("[FindAndDeleteContentInFile] - Error reading file: %s , error is %s", targetFile, err.Error())
return false
}
// 将文件内容按行分割
lines := strings.Split(string(fileContent), "\n")
// 过滤掉包含指定内容的行
var newLines []string
for _, line := range lines {
if !strings.Contains(line, content) {
newLines = append(newLines, line)
}
}
// 将过滤后的内容写回文件
err = os.WriteFile(targetFile, []byte(strings.Join(newLines, "\n")), 0644)
if err != nil {
log.Error("[FindAndDeleteContentInFile] - Error writing file: %s , error is %s", targetFile, err.Error())
return false
}
return true
}
// MoveFileToAnother 将源文件移动到目标文件
func MoveFileToAnother(srcFile, dstFile string) error {
// 如果dstFile是目录则将srcFile移动到dstFile目录下
if IsDirOrFile(dstFile) {
dstFile = filepath.Join(dstFile, filepath.Base(srcFile))
}
// 如果目标文件存在,则删除目标文件
if FileExists(dstFile) {
err := os.Remove(dstFile)
if err != nil {
return fmt.Errorf("删除目标文件失败: %w", err)
}
}
// 如果源文件不存在,则返回错误
if !FileExists(srcFile) {
return fmt.Errorf("源文件不存在: %s", srcFile)
}
// 如果目标文件夹不存在,则创建目标文件夹
if !FileExists(filepath.Dir(dstFile)) {
err := os.MkdirAll(filepath.Dir(dstFile), os.ModePerm)
if err != nil {
return fmt.Errorf("创建目标文件夹失败: %w", err)
}
}
// 移动文件
return os.Rename(srcFile, dstFile)
}
// MoveFolerToAnother 将源文件夹的所有文件递归移动到目标文件夹
func MoveFolerToAnother(srcDir, dstDir string) error {
// 读取源文件夹中的所有条目
entries, err := os.ReadDir(srcDir)
if err != nil {
return fmt.Errorf("读取源文件夹失败: %w", err)
}
// 创建目标文件夹(如果不存在)
if err := os.MkdirAll(dstDir, os.ModePerm); err != nil {
return fmt.Errorf("创建目标文件夹失败: %w", err)
}
// 遍历所有条目
for _, entry := range entries {
srcPath := filepath.Join(srcDir, entry.Name())
dstPath := filepath.Join(dstDir, entry.Name())
// 如果是文件夹,递归处理
if entry.IsDir() {
if err := MoveFolerToAnother(srcPath, dstPath); err != nil {
return fmt.Errorf("递归移动文件夹失败: %w", err)
}
} else {
// 移动文件
if err := os.Rename(srcPath, dstPath); err != nil {
return fmt.Errorf("移动文件失败: %w", err)
}
}
}
// 删除源文件夹
if err := os.RemoveAll(srcDir); err != nil {
return fmt.Errorf("删除源文件夹失败: %w", err)
}
return nil
}
// GetCurrentUserFolder 获取运行环境当前用户的根目录
func GetCurrentUserFolder() string {
usr, err := user.Current()
if err != nil {
fmt.Println(err)
return ""
}
return usr.HomeDir
}
// PermissionFile 设置文件权限
func permissionFile(filePath string, permission string) error {
// 将字符串权限转换为 FileMode
perm, err := strconv.ParseUint(permission, 8, 32)
if err != nil {
return fmt.Errorf("权限格式无效: %w", err)
}
return os.Chmod(filePath, os.FileMode(perm))
}
// PermissionFileExecute 设置文件可执行权限
func PermissionFileExecute(filePath string) error {
return permissionFile(filePath, "0777")
}
// PermissionFileRead 设置文件可读权限
func PermissionFileRead(filePath string) error {
return permissionFile(filePath, "0644")
}
// PermissionFileWrite 设置文件可写权限
func PermissionFileWrite(filePath string) error {
return permissionFile(filePath, "0666")
}