# Fileutil fileutil 包支持文件基本操作。
## 源码: - [https://github.com/duke-git/lancet/blob/main/fileutil/file.go](https://github.com/duke-git/lancet/blob/main/fileutil/file.go)
## 用法: ```go import ( "github.com/duke-git/lancet/v2/fileutil" ) ```
## 目录 - [ClearFile](#ClearFile) - [CreateFile](#CreateFile) - [CreateDir](#CreateDir) - [CopyFile](#CopyFile) - [CopyDir](#CopyDir) - [CurrentPath](#CurrentPath) - [FileMode](#FileMode) - [MiMeType](#MiMeType) - [IsExist](#IsExist) - [IsLink](#IsLink) - [IsDir](#IsDir) - [ListFileNames](#ListFileNames) - [RemoveFile](#RemoveFile) - [ReadFileToString](#ReadFileToString) - [ReadFileByLine](#ReadFileByLine) - [Zip](#Zip) - [ZipAppendEntry](#ZipAppendEntry) - [UnZip](#UnZip) - [IsZipFile](#IsZipFile) - [FileSize](#FileSize) - [MTime](#MTime) - [Sha](#Sha) - [ReadCsvFile](#ReadCsvFile) - [WriteCsvFile](#WriteCsvFile) - [WriteMapsToCsv](#WriteMapsToCsv) - [WriteStringToFile](#WriteStringToFile) - [WriteBytesToFile](#WriteBytesToFile) - [ReadFile](#ReadFile) - [ChunkRead](#ChunkRead) - [ParallelChunkRead](#ParallelChunkRead) - [GetVersion](#Version)
## 文档 ### ClearFile

清空文件内容

函数签名: ```go func ClearFile(path string) error ``` 示例:[运行](https://go.dev/play/p/NRZ0ZT-G94H) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.ClearFile("./test.txt") if err != nil { fmt.Println(err) } } ``` ### CreateFile

创建文件,创建成功返回true, 否则返回false

函数签名: ```go func CreateFile(path string) bool ``` 示例:[运行](https://go.dev/play/p/lDt8PEsTNKI) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { isCreatedSucceed := fileutil.CreateFile("./test.txt") fmt.Println(isCreatedSucceed) } ``` ### CreateDir

使用绝对路径创建嵌套目录,例如/a/, /a/b

函数签名: ```go func CreateDir(absPath string) error ``` 示例:[运行](https://go.dev/play/p/qUuCe1OGQnM) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.CreateDir("/a/b") // will create folder /a/b fmt.Println(err) } ``` ### CopyFile

拷贝文件,会覆盖原有的文件

函数签名: ```go func CopyFile(srcPath string, dstPath string) error ``` 示例:[运行](https://go.dev/play/p/Jg9AMJMLrJi) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.CopyFile("./test.txt", "./test_copy.txt") if err != nil { fmt.Println(err) } } ``` ### CopyDir

拷贝文件夹到目标路径,会递归复制文件夹下所有的文件及文件夹,并且访问权限也与源文件夹保持一致。当dstPath存在时会返回error

函数签名: ```go func CopyDir(srcPath string, dstPath string) error ``` 示例:[运行](https://go.dev/play/p/YAyFTA_UuPb) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.CopyFile("./test_src", "./test_dest") if err != nil { fmt.Println(err) } } ``` ### CurrentPath

返回当前位置的绝对路径。

函数签名: ```go func CurrentPath() string ``` 示例:[运行](https://go.dev/play/p/s74a9iBGcSw) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { absPath := CurrentPath() fmt.Println(absPath) } ``` ### FileMode

获取文件mode信息

函数签名: ```go func FileMode(path string) (fs.FileMode, error) ``` 示例:[运行](https://go.dev/play/p/2l2hI42fA3p) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { mode, err := fileutil.FileMode("./test.txt") if err != nil { fmt.Println(err) } fmt.Println(mode) } ``` ### MiMeType

获取文件mime类型, 'file'参数的类型必须是string或者*os.File

函数签名: ```go func MiMeType(file any) string ``` 示例:[运行](https://go.dev/play/p/bd5sevSUZNu) ```go package main import ( "fmt" "os" "github.com/duke-git/lancet/v2/fileutil" ) func main() { type1 := fileutil.MiMeType("./test.txt") fmt.Println(type1) //text/plain; charset=utf-8 f, _ := os.Open("./file.go") type2 := fileutil.MiMeType(f) fmt.Println(type2) //text/plain; charset=utf-8 } ``` ### IsExist

判断文件或目录是否存在

函数签名: ```go func IsExist(path string) bool ``` 示例:[运行](https://go.dev/play/p/nKKXt8ZQbmh) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { fileutil.CreateFile("./test.txt") isFileExist := fileutil.IsExist("./test.txt") fmt.Println(isFileExist) //true } ``` ### IsLink

判断文件是否是符号链接

函数签名: ```go func IsLink(path string) bool ``` 示例:[运行](https://go.dev/play/p/TL-b-Kzvf44) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { isLinkFile := fileutil.IsLink("./test.txt") fmt.Println(isLinkFile) //false } ``` ### IsDir

判断参数是否是目录

函数签名: ```go func IsDir(path string) bool ``` 示例:[运行](https://go.dev/play/p/WkVwEKqtOWk) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { isDir := fileutil.IsDir("./") fmt.Println(isDir) //true isDir = fileutil.IsDir("./test.txt") fmt.Println(isDir) //false } ``` ### ListFileNames

返回目录下所有文件名

函数签名: ```go func ListFileNames(path string) ([]string, error) ``` 示例:[运行](https://go.dev/play/p/Tjd7Y07rejl) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { fileNames, _ := fileutil.ListFileNames("./") fmt.Println(fileNames) } ``` ### RemoveFile

删除文件

函数签名: ```go func RemoveFile(path string) error ``` 示例:[运行](https://go.dev/play/p/P2y0XW8a1SH) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.RemoveFile("./test.txt") if err != nil { fmt.Println(err) } } ``` ### ReadFileToString

读取文件内容并返回字符串

函数签名: ```go func ReadFileToString(path string) (string, error) ``` 示例:[运行](https://go.dev/play/p/cmfwp_5SQTp) ```go package main import ( "fmt" "os" "github.com/duke-git/lancet/v2/fileutil" ) func main() { path := "./test.txt" fileutil.CreateFile(path) f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) f.WriteString("hello world") content, _ := fileutil.ReadFileToString(path) fmt.Println(content) //hello world } ``` ### ReadFileByLine

按行读取文件内容,返回字符串切片包含每一行

函数签名: ```go func ReadFileByLine(path string)([]string, error) ``` 示例:[运行](https://go.dev/play/p/svJP_7ZrBrD) ```go package main import ( "fmt" "os" "github.com/duke-git/lancet/v2/fileutil" ) func main() { path := "./text.txt" fileutil.CreateFile(path) f, _ := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0777) defer f.Close() f.WriteString("hello\nworld") contents, _ := fileutil.ReadFileByLine(path) fmt.Println(contents) //[]string{"hello", "world"} } ``` ### Zip

zip压缩文件, fpath参数可以是文件或目录

函数签名: ```go func Zip(fpath string, destPath string) error ``` 示例:[运行](https://go.dev/play/p/j-3sWBp8ik_P) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.Zip("./test.txt", "./test.zip") if err != nil { fmt.Println(err) } } ``` ### ZipAppendEntry

通过将单个文件或目录追加到现有的zip文件

函数签名: ```go func ZipAppendEntry(fpath string, destPath string) error ``` 示例:[运行](https://go.dev/play/p/cxvaT8TRNQp) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.ZipAppendEntry("./test.txt", "./test.zip") if err != nil { fmt.Println(err) } } ``` ### UnZip

zip解压缩文件并保存在目录中

函数签名: ```go func UnZip(zipFile string, destPath string) error ``` 示例:[运行](https://go.dev/play/p/g0w34kS7B8m) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { err := fileutil.Zip("./test.zip", "./unzip/test.txt") if err != nil { fmt.Println(err) } } ``` ### IsZipFile

判断文件是否是zip压缩文件。

函数签名: ```go func IsZipFile(filepath string) bool ``` 示例:[运行](https://go.dev/play/p/9M0g2j_uF_e) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { isZip := fileutil.IsZipFile("./zipfile.zip") fmt.Println(isZip) } ``` ### FileSize

返回文件字节大小。

函数签名: ```go func FileSize(path string) (int64, error) ``` 示例:[运行](https://go.dev/play/p/H9Z05uD-Jjc) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { size, err := fileutil.FileSize("./testdata/test.txt") fmt.Println(size) fmt.Println(err) // Output: // 20 // } ``` ### MTime

返回文件修改时间(unix timestamp).

函数签名: ```go func MTime(filepath string) (int64, error) ``` 示例:[运行](https://go.dev/play/p/s_Tl7lZoAaY) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { mtime, err := fileutil.MTime("./testdata/test.txt") fmt.Println(mtime) fmt.Println(err) // Output: // 1682391110 // } ``` ### Sha

返回文件sha值,参数`shaType` 应传值为: 1, 256,512.

函数签名: ```go func Sha(filepath string, shaType ...int) (string, error) ``` 示例:[运行](https://go.dev/play/p/VfEEcO2MJYf) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { sha1, err := fileutil.Sha("./testdata/test.txt", 1) sha256, _ := fileutil.Sha("./testdata/test.txt", 256) sha512, _ := fileutil.Sha("./testdata/test.txt", 512) fmt.Println(sha1) fmt.Println(sha256) fmt.Println(sha512) fmt.Println(err) // Output: // dda3cf10c5a6ff6c6659a497bf7261b287af2bc7 // aa6d0a3fbc3442c228d606da09e0c1dc98c69a1cac3da1909199e0266171df35 // d22aba2a1b7a2e2f512756255cc1c3708905646920cb1eb95e45b531ba74774dbbb89baebf1f716220eb9cf4908f1cfc5b2a01267704d9a59f59d77cab609870 // } ``` ### ReadCsvFile

读取csv文件内容到切片

函数签名: ```go func ReadCsvFile(filepath string, delimiter ...rune) ([][]string, error) ``` 示例:[运行](https://go.dev/play/p/OExTkhGEd3_u) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { content, err := fileutil.ReadCsvFile("./testdata/test.csv") fmt.Println(content) fmt.Println(err) // Output: // [[Bob 12 male] [Duke 14 male] [Lucy 16 female]] // } ``` ### WriteCsvFile

向csv文件写入内容。

函数签名: ```go func WriteCsvFile(filepath string, records [][]string, append bool, delimiter ...rune) error ``` 示例:[运行](https://go.dev/play/p/dAXm58Q5U1o) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { fpath := "./test.csv" fileutil.CreateFile(fpath) f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777) defer f.Close() data := [][]string{ {"Lili", "22", "female"}, {"Jim", "21", "male"}, } err := fileutil.WriteCsvFile(fpath, data, false) if err != nil { return } content, err := fileutil.ReadCsvFile(fpath) if err != nil { return } fmt.Println(content) // Output: // [[Lili 22 female] [Jim 21 male]] } ``` ### WriteMapsToCsv

将map切片写入csv文件中。

函数签名: ```go // filepath: CSV文件路径。 // records: 写入文件的map切片。map值必须为基本类型。会以map键的字母顺序写入。 // appendToExistingFile: 是否为追加写模式。 // delimiter: CSV文件分割符。 // headers: CSV文件表头顺序(需要与map key保持一致),不指定时按字母排序。 func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error ``` 示例:[运行](https://go.dev/play/p/umAIomZFV1c) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { fpath := "./test.csv" fileutil.CreateFile(fpath) f, _ := os.OpenFile(fpath, os.O_WRONLY|os.O_TRUNC, 0777) defer f.Close() records := []map[string]any{ {"Name": "Lili", "Age": "22", "Gender": "female"}, {"Name": "Jim", "Age": "21", "Gender": "male"}, } headers := []string{"Name", "Age", "Gender"} err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';', headers) if err != nil { log.Fatal(err) } content, err := fileutil.ReadCsvFile(csvFilePath, ';') fmt.Println(content) // Output: // [[Name Age Gender] [Lili 22 female] [Jim 21 male]] } ``` ### WriteBytesToFile

将bytes写入文件。

函数签名: ```go func WriteBytesToFile(filepath string, content []byte) error ``` 示例:[运行](https://go.dev/play/p/s7QlDxMj3P8) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { filepath := "./bytes.txt" file, err := os.Create(filepath) if err != nil { return } defer file.Close() err = fileutil.WriteBytesToFile(filepath, []byte("hello")) if err != nil { return } content, err := fileutil.ReadFileToString(filepath) if err != nil { return } os.Remove(filepath) fmt.Println(content) // Output: // hello } ``` ### WriteStringToFile

将字符串写入文件。

函数签名: ```go func WriteStringToFile(filepath string, content string, append bool) error ``` 示例:[运行](https://go.dev/play/p/GhLS6d8lH_g) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { filepath := "./test.txt" file, err := os.Create(filepath) if err != nil { return } defer file.Close() err = fileutil.WriteStringToFile(filepath, "hello", true) if err != nil { return } content, err := fileutil.ReadFileToString(filepath) if err != nil { return } os.Remove(filepath) fmt.Println(content) // Output: // hello } ``` ### ReadFile

读取文件或者URL。

函数签名: ```go func ReadFile(path string) (reader io.ReadCloser, closeFn func(), err error) ``` 示例:[运行](https://go.dev/play/p/uNep3Tr8fqF) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { reader, fn, err := fileutil.ReadFile("https://httpbin.org/robots.txt") if err != nil { return } defer fn() dat, err := io.ReadAll(reader) if err != nil { return } fmt.Println(string(dat)) // Output: // User-agent: * // Disallow: /deny } ``` ### ChunkRead

从文件的指定偏移读取块并返回块内所有行。

函数签名: ```go func ChunkRead(file *os.File, offset int64, size int, bufPool *sync.Pool) ([]string, error) ``` 示例:[运行](https://go.dev/play/p/r0hPmKWhsgf) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { const mb = 1024 * 1024 const defaultChunkSizeMB = 100 // test1.csv file content: // Lili,22,female // Jim,21,male filePath := "./testdata/test1.csv" // 替换为你的文件路径 f, err := os.Open(filePath) if err != nil { return } defer f.Close() var bufPool = sync.Pool{ New: func() interface{} { return make([]byte, 0, defaultChunkSizeMB*mb) }, } lines, err := fileutil.ChunkRead(f, 0, 100, &bufPool) if err != nil { return } fmt.Println(lines[0]) fmt.Println(lines[1]) // Output: // Lili,22,female // Jim,21,male } ``` ### ParallelChunkRead

并行读取文件并将每个块的行发送到指定通道。

函数签名: ```go // filePath:文件路径 // chunkSizeMB: 分块的大小(单位MB,设置为0时使用默认100MB),设置过大反而不利,视情调整 // maxGoroutine: 并发读取分块的数量,设置为0时使用CPU核心数 // linesCh: 用于接收返回结果的通道。 func ParallelChunkRead(filePath string, linesCh chan<- []string, chunkSizeMB, maxGoroutine int) error ``` 示例:[运行](https://go.dev/play/p/teMXnCsdSEw) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { const mb = 1024 * 1024 const defaultChunkSizeMB = 100 // 默认值 numParsers := runtime.NumCPU() linesCh := make(chan []string, numParsers) // test1.csv file content: // Lili,22,female // Jim,21,male filePath := "./testdata/test1.csv" go fileutil.ParallelChunkRead(filePath, linesCh, defaultChunkSizeMB, numParsers) var totalLines int for lines := range linesCh { totalLines += len(lines) for _, line := range lines { fmt.Println(line) } } fmt.Println(totalLines) // Output: // Lili,22,female // Jim,21,male // 2 } ``` ### GetExeDllVersion

返回exe,dll文件版本号(仅Window平台).

函数签名: ```go func GetExeDllVersion(filePath string) (string, error) ``` 示例:[运行](https://go.dev/play/p/s_Tl7lZoAaY) ```go package main import ( "fmt" "github.com/duke-git/lancet/v2/fileutil" ) func main() { v, err := fileutil.GetExeDllVersion(`C:\Program Files\Tencent\WeChat\WeChat.exe`) if err != nil { panic(err) } fmt.Println(v) // Output: // 3.9.10.19 } ```