From 3ce9ea57b8f0495529c4cfd3c6161d2b104b1af1 Mon Sep 17 00:00:00 2001 From: huangzj Date: Mon, 27 Apr 2020 11:26:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(Go-Tool)=EF=BC=9A=E6=96=B0=E5=BB=BA?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=AF=BB=E5=86=99=E3=80=81=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E3=80=81=E6=96=87=E4=BB=B6=E5=A4=B9=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- err/FileError.go | 45 ++++++++ util/FileReadTool.go | 68 +++++++++++ util/FileUtil.go | 254 ++++++++++++++++++++++++++++++++++++++++++ util/FileWriteTool.go | 48 ++++++++ 4 files changed, 415 insertions(+) create mode 100644 err/FileError.go create mode 100644 util/FileReadTool.go create mode 100644 util/FileUtil.go create mode 100644 util/FileWriteTool.go diff --git a/err/FileError.go b/err/FileError.go new file mode 100644 index 0000000..234c94d --- /dev/null +++ b/err/FileError.go @@ -0,0 +1,45 @@ +/* + * @Author : huangzj + * @Time : 2020/4/26 15:09 + * @Description: + */ + +package err + +type FileError struct { + Err error + Mes string +} + +func ENewFileError(err error) *FileError { + return &FileError{ + Err: err, + Mes: "", + } +} + +func NewFileError(mes string) *FileError { + return &FileError{ + Err: nil, + Mes: mes, + } +} + +func (e *FileError) Error() string { + if e == nil { + return "" + } + + if e.Err != nil { + return e.Err.Error() + } + + return e.Mes +} + +/* + * 默认Error方法直接返回Err信息,所以这边只需要加一个方法返回Mes就可以 + */ +func (e *FileError) ErrorMes() string { + return e.Mes +} diff --git a/util/FileReadTool.go b/util/FileReadTool.go new file mode 100644 index 0000000..2048fa9 --- /dev/null +++ b/util/FileReadTool.go @@ -0,0 +1,68 @@ +/* + * @Author : huangzj + * @Time : 2020/4/26 14:55 + * @Description: 文件读取工具 + */ + +package util + +import ( + err2 "Go-Tool/err" + "bufio" + "fmt" + "io" + "io/ioutil" + "os" +) + +/* + * @param 文件地址 + * @return string 文件内容 + * @return FileError 报错信息 + * @description 一次直接读取文件中的内容不进行中间处理 + */ +func ReadInOnce(filePath string) (string, *err2.FileError) { + err, is, _ := IsFileExist(filePath) + if err != nil { + return "", err2.ENewFileError(err) + } + if !is { + return "", err2.NewFileError("非文件") + } + + fd, iErr := ioutil.ReadFile(filePath) + if iErr != nil { + return "", err2.ENewFileError(iErr) + } + + return string(fd), nil +} + +/* + * @param filePath 文件地址 + * @return string 读取的文件内容 + * @return FileError 读取错误,如果没有错误返回nil + * @description 通过for循环去读取文件,这边提供一种读取方式,通过这种方式来处理对应读取的操作 + */ +func ReadByCircle(filePath string) (string, *err2.FileError) { + var fs string + file, err := os.Open(filePath) + if err != nil { + return "", err2.ENewFileError(err) + } + defer file.Close() + + inputReader := bufio.NewReader(file) + for { + inputString, readerError := inputReader.ReadString('\n') + if readerError == io.EOF { + if inputString != "" { + fs = fmt.Sprint(fs, inputString) + } + break + } + fs = fmt.Sprint(fs, inputString) + } + + return fs, nil +} diff --git a/util/FileUtil.go b/util/FileUtil.go new file mode 100644 index 0000000..5084ef8 --- /dev/null +++ b/util/FileUtil.go @@ -0,0 +1,254 @@ +/* + * @Author : huangzj + * @Time : 2020/4/26 14:56 + * @Description: 文件工具,主要处理权限、文件创建等操作 + * + * + * 打开文件的权限相关: + * os.O_RDONLY // 只读 + * os.O_WRONLY // 只写 + * os.O_RDWR // 读写 + * os.O_APPEND // 往文件中添建(Append) + * os.O_CREATE // 如果文件不存在则先创建 + * os.O_TRUNC // 文件打开时裁剪文件 + * os.O_EXCL // 和O_CREATE一起使用,文件不能存在 + * os.O_SYNC // 以同步I/O的方式打开 + * + */ + +package util + +import ( + err2 "Go-Tool/err" + "fmt" + "io/ioutil" + "os" +) + +/* + * @param path 文件夹目录 + * @return err 如果报错返回错误信息,否则返回nil + * @return bool 返回是否文件夹结果 + * @return os.FileInfo 返回FileInfo对象,如果没有的话返回nil + * @description + */ +func IsDirExist(path string) (*err2.FileError, bool, os.FileInfo) { + dir, err := os.Stat(path) + //如果路仅错误直接返回错误 + if err != nil { + return err2.ENewFileError(err), false, nil + } + //如果是文件夹直接返回 + if dir.IsDir() { + return nil, true, dir + } + return err2.NewFileError("非文件夹"), false, nil +} + +func IsFileExist(path string) (*err2.FileError, bool, os.FileInfo) { + file, err := os.Stat(path) + //如果路仅错误直接返回错误 + if err != nil { + return err2.ENewFileError(err), false, nil + } + + if file.IsDir() { + return err2.NewFileError("非文件"), false, nil + } + + return nil, true, file +} + +/* + * @param filepath 文件目录 + * @return err 如果报错返回错误信息,否则返回nil + * @return bool 是否有读权限 + * @return *File 返回文件对象,如果没有返回nil + * @description 这边需要注意的是,在打开文件的时候,如果报错,分两种情况,一个是没权限,一个是文件有问题 + */ +func HasReadPermission(filePath string) (*err2.FileError, bool, *os.File) { + eErr, exist, _ := IsFileExist(filePath) + if eErr != nil || !exist { + return err2.ENewFileError(eErr), false, nil + } + file, err := os.OpenFile(filePath, os.O_RDONLY, 0666) + if err != nil { + //如果是没权限的错误返回 + if os.IsPermission(err) { + return err2.ENewFileError(err), false, nil + } + //如果有权限但是发生错误的话,返回错误和有权限的标识 + return err2.ENewFileError(err), true, nil + } + + return nil, true, file +} + +/* + * @param filepath 文件目录 + * @return err 如果报错返回错误信息,否则返回nil + * @return bool 是否有写权限 + * @return *File 返回文件对象,如果没有返回nil + * @description 这边需要注意的是,在打开文件的时候,如果报错,分两种情况,一个是没权限,一个是文件有问题 + */ +func HasWritePermission(filePath string) (*err2.FileError, bool, *os.File) { + eErr, exist, _ := IsFileExist(filePath) + if eErr != nil || !exist { + return err2.ENewFileError(eErr), false, nil + } + file, err := os.OpenFile(filePath, os.O_WRONLY, 0666) + if err != nil { + //如果是没权限的错误返回 + if os.IsPermission(err) { + return err2.ENewFileError(err), false, nil + } + //如果有权限但是发生错误的话,返回错误和有权限的标识 + return err2.ENewFileError(err), true, nil + } + + return nil, true, file +} + +/* + * @param filepath 文件目录 + * @return err 如果报错返回错误信息,否则返回nil + * @return bool 是否有写权限 + * @return *File 返回文件对象,如果没有返回nil + * @description 判断对文件是否有读写权限. + */ +func HasReadWritePermission(filePath string) (*err2.FileError, bool, *os.File) { + rErr, hasR, rFile := HasReadPermission(filePath) + wErr, hasW, _ := HasWritePermission(filePath) + if hasR && hasW { + return nil, true, rFile + } + + if rErr != nil { + return err2.ENewFileError(rErr), false, nil + } + + return err2.ENewFileError(wErr), false, nil +} + +/* + * @param filePath 文件路径 + * @return FileError 文件错误 + * @return File文件指针对象 + * @description 创建文件,如果文件存在不进行覆盖 + */ +func CreateFile(filePath string) (*err2.FileError, *os.File) { + file, err := os.Create(filePath) + if err != nil { + return err2.ENewFileError(err), nil + } + return nil, file +} + +/* + * @param filePath 文件路径 + * @return FileError 文件错误 + * @return File文件指针对象 + * @description 创建文件,如果文件存在进行覆盖 + */ +func CreateOrCoverFile(filePath string) (*err2.FileError, *os.File) { + _, has, _ := IsFileExist(filePath) + + if has { + rErr := os.Remove(filePath) + if rErr != nil { + return err2.ENewFileError(rErr), nil + } + return CreateFile(filePath) + } + return CreateFile(filePath) +} + +/* + * @param filePath 文件路径 + * @return File文件指针对象 + * @description 获取文件夹下面的所有文件对象数组 + */ +func GetAllFileFromDir(filePath string) []*os.File { + return getFiles(filePath) +} + +/* + * @param + * @return + * @description 删除文件夹下面所有的空文件夹 + */ +func DeleteEmptyDir(filePath string) *err2.FileError { + err, is, _ := IsDirExist(filePath) + if err != nil { + return err2.ENewFileError(err) + } + if !is { + return err2.NewFileError("非文件夹") + } + + //拿到所有的空文件夹 + emptyDirList := getEmptyDir(filePath) + for _, row := range emptyDirList { + err := os.RemoveAll(row) + if err != nil { + return err2.ENewFileError(err) + } + } + + return nil +} + +/* + * @param dir 文件夹地址 + * @return 所有空文件夹数组 + * @description 获取文件夹下面所有的空文件夹数组 + */ +func GetAllEmptyDir(dir string) (*err2.FileError, []string) { + err, is, _ := IsDirExist(dir) + if err != nil { + return err2.ENewFileError(err), nil + } + if !is { + return err2.NewFileError("非文件夹"), nil + } + return nil, getEmptyDir(dir) +} + +func getEmptyDir(dir string) []string { + emptyDirList := make([]string, 0) + info, err := ioutil.ReadDir(dir) + if err != nil { + return nil + } + for _, f := range info { + if f.IsDir() { + list := getFiles(fmt.Sprint(dir, "\\", f.Name())) + if list == nil || len(list) == 0 { + emptyDirList = append(emptyDirList, dir) + } + } + } + + return emptyDirList +} + +func getFiles(filePath string) []*os.File { + fileList := make([]*os.File, 0) + info, err := ioutil.ReadDir(filePath) + if err != nil { + return nil + } + + for _, f := range info { + if f.IsDir() { + list := getFiles(fmt.Sprint(filePath, "\\", f.Name())) + if list != nil { + for _, row := range list { + fileList = append(fileList, row) + } + } + } + } + + return fileList +} diff --git a/util/FileWriteTool.go b/util/FileWriteTool.go new file mode 100644 index 0000000..7f4800b --- /dev/null +++ b/util/FileWriteTool.go @@ -0,0 +1,48 @@ +/* + * @Author : huangzj + * @Time : 2020/4/26 14:56 + * @Description: 文件写入工具 + */ + +package util + +import ( + err2 "Go-Tool/err" + "io/ioutil" + "os" +) + +/* + * @param filePath 文件位置 + * @param content 文件内容 + * @return + * @description + */ +func WriteByIoUtil(filePath, content string) *err2.FileError { + err := ioutil.WriteFile(filePath, []byte(content), 0644) + if err != nil { + return err2.ENewFileError(err) + } + return nil +} + +/* + * @param filePath 文件位置 + * @param content 文件内容 + * @return FileError错误信息 + * @return File 文件对象,成功写入才会返回文件对象,否则是nil + * @description + */ +func WriteByFile(filePath, content string) (*err2.FileError, *os.File) { + fileObj, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err2.ENewFileError(err), nil + } + defer fileObj.Close() + + if _, err := fileObj.WriteString(content); err != nil { + return err2.ENewFileError(err), nil + } + + return nil, fileObj +}