package fileutils import ( "archive/zip" "bytes" "io" "log" "os" "path/filepath" "strings" ) // PathExists 检查对应路径的文件或目录是否存在 // 参数: // path: 文件或目录的路径 // 返回值: // 对应路径的文件或目录是否存在 func PathExists(path string) bool { _, err := os.Stat(path) if err == nil { return true } if os.IsNotExist(err) { return false } return false } // GetDirFiles 获取目录下的文件 // 参数 // dir: 目录的路径 // 返回值: // 目录下的文件路径(用dir拼接,dir是绝对路径就是绝对路径,dir是相对路径就是相对路径)和错误 func GetDirFiles(dir string) ([]string, error) { dirList, err := os.ReadDir(dir) if err != nil { return nil, err } filesRet := make([]string, 0) for _, file := range dirList { if file.IsDir() { files, err := GetDirFiles(filepath.Join(dir, file.Name())) if err != nil { return nil, err } filesRet = append(filesRet, files...) } else { filesRet = append(filesRet, filepath.Join(dir, file.Name())) } } return filesRet, nil } // ReadFileWithBuffer 带缓冲读文件,一般用于大文件读取 // 参数 // filePath: 文件的路径 // bufferSize: 缓冲大小,每次最多读取的字节数 // readCallback: 每次读取回调 // 返回值: // 错误 func ReadFileWithBuffer(filePath string, bufferSize int, readCallback func(b []byte)) error { file, err := os.Open(filePath) if err != nil { return err } for { buffer := make([]byte, bufferSize) readSize, err := file.Read(buffer) if err != nil && err != io.EOF { return err } if readCallback != nil { readCallback(buffer[:readSize]) } if err != nil && err == io.EOF { break } } return nil } // ZipDir zip压缩目录 // 参数 // dirPath: 目录的路径 // savePath: 生成zip文件的路径 // 返回值: // 错误 func ZipDir(dirPath string, savePath string) error { archive, err := os.Create(savePath) if err != nil { return err } defer func(archive *os.File) { err := archive.Close() if err != nil { log.Println(err) return } }(archive) zipWriter := zip.NewWriter(archive) defer func(zipWriter *zip.Writer) { err := zipWriter.Close() if err != nil { log.Println(err) return } }(zipWriter) err = filepath.Walk(dirPath, func(path string, f os.FileInfo, err error) error { if err != nil { return err } if f.IsDir() { return nil } zipPath := strings.TrimPrefix(path, dirPath) err = writeZipFile(path, zipPath, zipWriter) if err != nil { return err } return nil }) if err != nil { return err } return nil } // UnzipFile 解压缩zip文件 // 参数 // zipFilePath: zip文件路径 // destDir: 解压缩的目的目录 // 返回值: // 错误 func UnzipFile(zipFilePath string, destDir string) error { srcFile, err := os.Open(zipFilePath) if err != nil { return err } defer func() { err := srcFile.Close() if err != nil { log.Println(err) return } }() srcFileInfo, err := srcFile.Stat() if err != nil { return err } return unzip(srcFile, srcFileInfo.Size(), destDir) } // UnzipBytes 解压zip文件 // 参数 // zipFileBytes: zip文件的字节内容 // destDir: 解压缩的目的目录 // 返回值: // 错误 func UnzipBytes(zipFileBytes []byte, destDir string) error { return unzip(bytes.NewReader(zipFileBytes), int64(len(zipFileBytes)), destDir) } func writeZipFile(filePath string, zipPath string, zipWriter *zip.Writer) error { file, err := os.Open(filePath) if err != nil { return err } defer func() { err := file.Close() if err != nil { log.Println(err) return } }() writer, err := zipWriter.Create(zipPath) if err != nil { return err } _, err = io.Copy(writer, file) if err != nil { return err } return nil } func unzip(r io.ReaderAt, size int64, destDir string) error { zipReader, err := zip.NewReader(r, size) if err != nil { return err } for _, f := range zipReader.File { fPath := filepath.Join(destDir, f.Name) if f.FileInfo().IsDir() { if err := os.MkdirAll(fPath, os.ModePerm); err != nil { return err } } else { if err := os.MkdirAll(filepath.Dir(fPath), os.ModePerm); err != nil { return err } inFile, err := f.Open() if err != nil { return err } outFile, err := os.OpenFile(fPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } if _, err = io.Copy(outFile, inFile); err != nil { return err } if err = inFile.Close(); err != nil { return err } if err = outFile.Close(); err != nil { return err } } } return nil }