dalin hace 1 mes
padre
commit
913a90cbd3
Se han modificado 2 ficheros con 593 adiciones y 0 borrados
  1. 411 0
      gio/directory.go
  2. 182 0
      gio/fileInfo.go

+ 411 - 0
gio/directory.go

@@ -0,0 +1,411 @@
+package gio
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"slices"
+	"strings"
+)
+
+type Directory struct {
+	Path string
+	Name string
+	//Children []Directory
+	//Files    []File
+}
+
+// GetFilesAll 获取文件夹中的文件(包含子文件夹)
+func (d *Directory) GetFilesAll() []File {
+	return nil
+}
+
+// GetChildrenDirs 获取子文件夹
+func (d *Directory) GetChildrenDirs() []Directory {
+
+	var dirs []Directory
+
+	// 读取目录内容
+	files, err := os.ReadDir(d.Path)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return nil
+	}
+	// 遍历第一层子目录
+	for _, file := range files {
+		if file.IsDir() {
+			//fmt.Println("Dir:", file.Name())
+			dirs = append(dirs, Directory{Path: d.Path + string(os.PathSeparator) + file.Name(), Name: file.Name()})
+		}
+		//else {
+		//	fmt.Println("File:", file.Name())
+		//}
+	}
+	if len(dirs) == 0 {
+		return nil
+	}
+	return dirs
+
+}
+
+// CopyFile 使用io.Copy进行文件的复制,同时也会复制文件的所有权限
+// @param src 复制文件
+// @param des 目标文件
+// @return error 错误信息
+func CopyFile(src, des string) error {
+	// 判断文件是否存在
+	if !IsExist(src) {
+		return errors.New("要复制的文件不存在")
+	}
+
+	// 打开文件
+	srcFile, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer func(srcFile *os.File) {
+		err := srcFile.Close()
+		if err != nil {
+
+		}
+	}(srcFile)
+
+	// 获取源文件的权限
+	fi, _ := srcFile.Stat()
+	perm := fi.Mode()
+
+	// 创建目标文件,并复制源文件的所有权限
+	desFile, err := os.OpenFile(des, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
+	if err != nil {
+		return err
+	}
+	defer desFile.Close()
+
+	// 进行复制
+	_, err = io.Copy(desFile, srcFile)
+
+	// 返回
+	return err
+}
+
+func moveDir(sourceDir string, targetDir string) error {
+	dirpath := filepath.Dir(targetDir)
+	if !IsExist(dirpath) {
+
+		err := CreateDir(dirpath)
+		if err != nil {
+			return err
+		}
+	}
+
+	fs, err := os.ReadDir(sourceDir)
+	if err == nil {
+		//遍历当前文件夹
+		for _, f := range fs {
+			//判断是否是文件夹
+			if f.IsDir() {
+				err = moveDir(sourceDir+string(os.PathSeparator)+f.Name(), targetDir+string(os.PathSeparator)+f.Name())
+				if err != nil {
+					return err
+				}
+			} else {
+				//判断到是文件
+
+				//创建文件夹
+				_ = os.Mkdir(targetDir, os.ModePerm)
+				//使用重命名方法移动文件
+				err := CopyFile(sourceDir+string(os.PathSeparator)+f.Name(), targetDir+string(os.PathSeparator)+f.Name())
+				if err != nil {
+					return err
+				}
+				err = os.Remove(sourceDir + string(os.PathSeparator) + f.Name())
+				return err
+			}
+		}
+	}
+	//fs2, err := os.ReadDir(sourceDir)
+	//if err == nil {
+	//	if len(fs2) == 0 {
+	//		_ = os.Remove(sourceDir)
+	//	}
+	//} else {
+	//	return err
+	//}
+	return nil
+}
+func copyDir(sourceDir string, targetDir string) error {
+
+	dirpath := filepath.Dir(targetDir)
+	if !IsExist(dirpath) {
+
+		err := CreateDir(dirpath)
+		if err != nil {
+			return err
+		}
+	}
+
+	fs, err := os.ReadDir(sourceDir)
+	if err == nil {
+		//遍历当前文件夹
+		for _, f := range fs {
+			//判断是否是文件夹
+			if f.IsDir() {
+				err = copyDir(sourceDir+string(os.PathSeparator)+f.Name(), targetDir+string(os.PathSeparator)+f.Name())
+				if err != nil {
+					return err
+				}
+			} else {
+				//判断到是文件
+
+				//创建文件夹
+
+				err := CreateDir(targetDir)
+				if err != nil {
+					return err
+				}
+				//使用重命名方法移动文件
+				err = CopyFile(sourceDir+string(os.PathSeparator)+f.Name(), targetDir+string(os.PathSeparator)+f.Name())
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// Move 移动文件夹
+func (d *Directory) Move(targetDir string) error {
+
+	err := moveDir(d.Path, targetDir)
+	return err
+}
+
+// Copy 复制文件夹
+func (d *Directory) Copy(targetDir string) error {
+
+	err := copyDir(d.Path, targetDir)
+	return err
+}
+
+func deleteall(path string) error {
+	fs, err := os.ReadDir(path)
+	if err == nil {
+		//遍历当前文件夹
+		for _, f := range fs {
+			//判断是否是文件夹
+			if f.IsDir() {
+				_ = deleteall(path + string(os.PathSeparator) + f.Name())
+			} else {
+				//删除文件
+				_ = os.Remove(path + string(os.PathSeparator) + f.Name())
+
+			}
+		}
+	}
+	_ = os.Remove(path)
+	if IsExist(path) {
+		return nil
+	} else {
+		return errors.New("无法删除该文件夹")
+	}
+
+}
+
+// DeleteAll 删除当前文件夹的所有内容
+func (d *Directory) DeleteAll() error {
+
+	return deleteall(d.Path)
+}
+
+// Rename 重命名文件夹
+func (d *Directory) Rename(newName string) error {
+	return os.Rename(d.Path, filepath.Dir(d.Path)+string(os.PathSeparator)+newName)
+}
+
+// GetParent 获取父级文件夹路径
+func (d *Directory) GetParent() *Directory {
+
+	sp := slices.DeleteFunc(strings.Split(d.Path, string(os.PathSeparator)), func(s string) bool {
+		return s == ""
+	})
+	var tpath string
+	for i, v := range sp {
+
+		if i < len(sp)-1 {
+			if i == 0 {
+				tpath += v
+
+			} else {
+				tpath += string(os.PathSeparator) + v
+			}
+		}
+	}
+	return OpenDir(tpath)
+}
+
+// GetFile 通过文件名获取文件
+func (d *Directory) GetFile(name string) ([]*File, error) {
+
+	return nil, nil
+}
+
+// GetDir 通过文件夹名获取文件夹
+func (d *Directory) GetDir(name string) ([]*Directory, error) {
+
+	return nil, nil
+}
+
+// GetALLDir 获取当前目录所有的子文件夹
+func (d *Directory) GetALLDir() []*Directory {
+
+	var dirs []*Directory
+	fs, err := os.ReadDir(d.Path)
+	if err == nil {
+		//遍历当前文件夹
+		for _, f := range fs {
+			//判断是否是文件夹
+			if f.IsDir() {
+				dirs = append(dirs, OpenDir(d.Path+string(os.PathSeparator)+f.Name()))
+			}
+		}
+	}
+	return dirs
+}
+
+func getallfile(path string) []*File {
+	var files []*File
+	fs, err := os.ReadDir(path)
+	if err == nil {
+		//遍历当前文件夹
+		for _, f := range fs {
+			//判断是否是文件夹
+			if f.IsDir() {
+				tfs := getallfile(path + string(os.PathSeparator) + f.Name())
+				for _, v := range tfs {
+					files = append(files, v)
+				}
+			} else {
+				tf, _ := OpenFile(path + string(os.PathSeparator) + f.Name())
+				if tf != nil {
+					files = append(files, tf)
+				}
+			}
+		}
+	}
+	return files
+}
+
+// GetALLDir 获取当前目录所有的子文件夹
+func (d *Directory) GetAllFile(isSearchSubDir bool) []*File {
+	if isSearchSubDir {
+		return getallfile(d.Path)
+
+	} else {
+		var files []*File
+		fs, err := os.ReadDir(d.Path)
+		if err == nil {
+			//遍历当前文件夹
+			for _, f := range fs {
+				//判断是否是文件夹
+				if !f.IsDir() {
+					tf, _ := OpenFile(d.Path + string(os.PathSeparator) + f.Name())
+					if tf != nil {
+						files = append(files, tf)
+					}
+				}
+			}
+		}
+		return files
+	}
+
+}
+
+// OpenDir 打开文件夹
+func OpenDir(path string) *Directory {
+
+	d := Directory{Path: path, Name: filepath.Base(path)}
+
+	return &d
+}
+
+//// IsExistDir 判断文件夹是否存在
+//func IsExistDir(path string) bool {
+//
+//	return false
+//}
+
+// IsExist 判断是否存在
+func IsExist(path string) bool {
+	existed := true
+	if _, err := os.Stat(path); os.IsNotExist(err) {
+		existed = false
+	}
+	return existed
+
+}
+
+// IsExist 判断是否存在
+func (d *Directory) IsExist() bool {
+	existed := true
+	if _, err := os.Stat(d.Path); os.IsNotExist(err) {
+		existed = false
+	}
+	return existed
+
+}
+
+// CreateDir 创建文件夹
+func createDir(path string) error {
+	// 使用Mkdir创建文件夹
+	err := os.Mkdir(path, os.ModePerm)
+	if err != nil {
+		// 如果文件夹已存在,也可以选择忽略错误
+		if !os.IsExist(err) {
+			return nil
+		}
+		return err
+	}
+	return nil
+}
+
+// CreateDir 创建文件夹
+func CreateDir(dirpath string) error {
+	//os.PathSeparator
+
+	sp := slices.DeleteFunc(strings.Split(dirpath, string(os.PathSeparator)), func(s string) bool {
+		return s == ""
+	})
+	var tpath string
+	for i, v := range sp {
+
+		if i == 0 {
+			tpath += v
+			if !IsExist(v) {
+				return errors.New("不存在\"" + v + "\"路径")
+			}
+		} else {
+			tpath += string(os.PathSeparator) + v
+			if !IsExist(tpath) {
+				//err := CreateDir(tpath)
+				//if err != nil {
+				//	return err
+				//}
+				err := os.Mkdir(tpath, os.ModePerm)
+				if err != nil {
+					// 如果文件夹已存在,也可以选择忽略错误
+					if !os.IsExist(err) {
+						return nil
+					}
+					return err
+				}
+
+			}
+
+		}
+
+	}
+	return nil
+}

+ 182 - 0
gio/fileInfo.go

@@ -0,0 +1,182 @@
+package gio
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"golang.org/x/sys/windows"
+	"io"
+	"os"
+	"path/filepath"
+	"runtime"
+	"syscall"
+	"time"
+)
+
+const ()
+
+type File struct {
+	//文件名(包含后缀)
+	Name string
+	//文件大小
+	Size int64
+	//创建时间
+	CreateTime time.Time
+
+	//文件后缀
+	Ext string
+	//完整路径
+	Path string
+	//IsOnlyRead bool
+
+	//修改时间
+	ModifyTime time.Time
+	//文件是否被隐藏(window)
+	IsHidden   bool
+	IsCanRead  bool
+	IsCanWrite bool
+}
+
+// SetHiddenAtt 设置隐藏属性
+func (f *File) SetHiddenAtt(ishidden bool) error {
+	return setFileHiddenAtt(f.Path, ishidden)
+}
+
+// ToHash 获取哈希值
+func (f *File) ToHash() (string, error) {
+	ff, err := os.OpenFile(f.Path, os.O_RDONLY, os.ModePerm)
+	if err != nil {
+		return "", err
+	}
+	defer func(f *os.File) {
+		_ = f.Close()
+	}(ff)
+
+	hash := md5.New()
+	if _, err := io.Copy(hash, ff); err != nil {
+		return "", err
+	}
+
+	return hex.EncodeToString(hash.Sum(nil)), nil
+}
+
+// Content 获取内容,返回[]byte指针则修改源文件内容
+func (f *File) Content(fn func(bs []byte) *[]byte) error {
+	ff, err := os.OpenFile(f.Path, os.O_RDONLY|os.O_WRONLY, os.ModePerm)
+	if err != nil {
+		return err
+	}
+	defer func(f *os.File) {
+		_ = f.Close()
+	}(ff)
+
+	buffer, err := os.ReadFile(f.Path)
+	nbs := fn(buffer)
+	if nbs != nil {
+		// 清空文件内容
+		_ = ff.Truncate(0)
+		_, _ = ff.Seek(0, 0)
+		// 写入新内容
+		_, err := ff.Write(*nbs)
+		return err
+	}
+	return nil
+}
+
+// Delete 删除文件
+func (f *File) Delete() error {
+	err := os.Remove(f.Path)
+	return err
+}
+
+// isFileHidden 判断文件是否被隐藏(windnow)
+func isFileHidden(path string) (bool, error) {
+	pathPtr, err := syscall.UTF16PtrFromString(path)
+	if err != nil {
+		return false, err
+	}
+	attributes, err := windows.GetFileAttributes(pathPtr)
+	if err != nil {
+		return false, err
+	}
+	return attributes&windows.FILE_ATTRIBUTE_HIDDEN == windows.FILE_ATTRIBUTE_HIDDEN, nil
+
+}
+
+// setFileHiddenAtt 设置文件隐藏属性
+func setFileHiddenAtt(path string, ishidden bool) error {
+	pathp, err := syscall.UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+
+	if ishidden {
+		// 应用新的文件属性
+		return windows.SetFileAttributes(pathp, windows.FILE_ATTRIBUTE_HIDDEN)
+	} else {
+		return windows.SetFileAttributes(pathp, windows.FILE_ATTRIBUTE_NORMAL)
+	}
+
+}
+
+// OpenFile 打开文件 返回文件以及错误信息
+func OpenFile(path string) (*File, error) {
+
+	f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm)
+	if err != nil {
+		return nil, err
+	}
+	defer func(f *os.File) {
+		_ = f.Close()
+	}(f)
+	fileinfo, err := f.Stat()
+	if err != nil {
+		return nil, err
+	}
+
+	var createTime int64
+
+	var modifyTime int64
+
+	ishidden := false
+
+	if runtime.GOOS == "windows" {
+
+		//获取文件信息
+		winFileAttr := fileinfo.Sys().(*syscall.Win32FileAttributeData)
+		createTime = winFileAttr.CreationTime.Nanoseconds() / 1e9
+		modifyTime = winFileAttr.LastWriteTime.Nanoseconds() / 1e9
+		t, _ := isFileHidden(path)
+		if t {
+			ishidden = true
+		}
+
+	} else if runtime.GOOS == "linux" {
+
+	}
+
+	//ti := time.Now()
+	//fmt.Println(ti)
+	loc, _ := time.LoadLocation("Asia/Shanghai")
+	tf := File{Name: f.Name(),
+		Size:       fileinfo.Size(),
+		CreateTime: time.Unix(createTime, 0).In(loc),
+		ModifyTime: time.Unix(modifyTime, 0).In(loc),
+		Path:       path, Ext: filepath.Ext(path),
+		IsHidden: ishidden,
+	}
+
+	mode := fileinfo.Mode()
+	if mode&0400 == 0400 {
+		tf.IsCanRead = true
+	} else {
+		tf.IsCanRead = false
+	}
+	if mode&0200 == 0200 {
+		tf.IsCanWrite = true
+	} else {
+		tf.IsCanWrite = false
+	}
+
+	return &tf, nil
+
+}