Go 文件
最后修改时间 2024 年 4 月 11 日
在本文中,我们将展示如何在 Golang 中处理文件。我们读取文件、写入文件、创建文件、列出文件以及确定它们的大小和修改时间。
要在 Go 中处理文件,我们使用 os
、ioutil
和 fmt
包。
os.Stat
函数返回描述文件的 FileInfo
结构。
Go 检查文件是否存在
在下面的示例中,我们检查给定文件是否存在。
package main import ( "errors" "fmt" "os" ) func main() { _, err := os.Stat("words.txt") if errors.Is(err, os.ErrNotExist) { fmt.Println("file does not exist") } else { fmt.Println("file exists") } }
我们在文件上调用 os.Stat
函数。如果函数返回 os.ErrNotExist
错误,则表示文件不存在。
Go 创建文件
os.Create
函数创建或截断给定文件。如果文件已存在,则将其截断。如果文件不存在,则以 0666 模式创建。
package main import ( "fmt" "log" "os" ) func main() { file, err := os.Create("empty.txt") defer file.Close() if err != nil { log.Fatal(err) } fmt.Println("file created") }
该示例创建一个空文件。
Go 删除文件
os.Remove
删除给定文件。
package main import ( "fmt" "log" "os" ) func main() { err := os.Remove("words.txt") if err != nil { log.Fatal(err) } fmt.Println("file deleted") }
该示例删除一个文件。
Go 文件大小
在下面的示例中,我们获取文件大小。
package main import ( "fmt" "log" "os" ) func main() { fInfo, err := os.Stat("words.txt") if err != nil { log.Fatal(err) } fsize := fInfo.Size() fmt.Printf("The file size is %d bytes\n", fsize) }
首先,我们使用 os.Stat
获取 FileInfo
结构。然后,我们使用 Size
函数从结构中获取文件大小(以字节为单位)。
Go 文件最后修改时间
在下面的示例中,我们获取给定文件的最后修改时间。
package main import ( "fmt" "log" "os" ) func main() { fileName := "words.txt" fileInfo, err := os.Stat(fileName) if err != nil { log.Fatal(err) } mTime := fileInfo.ModTime() fmt.Println(mTime) }
我们使用 FileInfo
结构中的 ModTime
函数获取最后修改时间。
Go 读取文件
ioutil.ReadFile
读取参数指定的文件并返回其内容。该函数一次性读取整个文件;因此,不应将其用于大文件。
package main import ( "fmt" "io/ioutil" "log" ) func main() { content, err := ioutil.ReadFile("words.txt") if err != nil { log.Fatal(err) } fmt.Println(string(content)) }
在代码示例中,我们读取文本文件的内容并将其打印到控制台。
对于大文件,更合适的方法是逐行读取。这样程序就不会占用大量内存。
package main import ( "bufio" "fmt" "log" "os" ) func main() { f, err := os.Open("words.txt") if err != nil { log.Fatal(err) } defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { log.Fatal(err) } }
该示例逐行读取文本文件。
f, err := os.Open("words.txt")
os.Open
函数打开指定文件进行读取。如果成功,返回的文件上的函数可用于读取;关联的文件描述符模式为 O_RDONLY
。
scanner := bufio.NewScanner(f)
bufio.NewScanner
函数返回一个新的 Scanner
用于读取。
for scanner.Scan() { fmt.Println(scanner.Text()) }
使用 Scan
函数,我们前进到下一个令牌。我们使用 Text
函数获取文本。在默认模式下,Scan
函数按行前进。
Go 写入文件
ioutil.WriteFile
函数将数据写入指定文件。如果文件不存在,则创建它;否则,在写入之前将其截断。
package main import ( "fmt" "io/ioutil" "log" ) func main() { fileName := "data.txt" val := "old\nfalcon\nsky\ncup\nforest\n" data := []byte(val) err := ioutil.WriteFile(fileName, data, 0644) if err != nil { log.Fatal(err) } fmt.Println("done") }
该示例将几个词写入文件。
val := "old\nfalcon\nsky\ncup\nforest\n" data := []byte(val)
我们有一个字符串,从中创建一个字节切片。
err := ioutil.WriteFile(fileName, data, 0644)
我们以 0644 的权限将字节切片写入给定的文件名。
在下一个示例中,我们将字符串切片写入文件。
package main import ( "fmt" "log" "os" ) func main() { fileName := "data.txt" f, err := os.Create(fileName) if err != nil { log.Fatal(err) } defer f.Close() words := []string{"sky", "falcon", "rock", "hawk"} for _, word := range words { _, err := f.WriteString(word + "\n") if err != nil { log.Fatal(err) } } fmt.Println("done") }
WriteString
方法将字符串写入文件。
Go 追加到文件
为了追加到文件,我们将 os.O_APPEND
标志包含在 os.OpenFile
函数的标志中。
package main import ( "log" "os" ) func main() { fileName := "words.txt" f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Fatal(err) } defer f.Close() if _, err := f.WriteString("cloud\n"); err != nil { log.Fatal(err) } }
该示例使用 WriteString
函数将一个词追加到 words.txt
文件。
Go 复制文件
下一个示例复制文件。
package main import ( "io/ioutil" "log" ) func main() { src := "words.txt" dest := "words2.txt" bytesRead, err := ioutil.ReadFile(src) if err != nil { log.Fatal(err) } err = ioutil.WriteFile(dest, bytesRead, 0644) if err != nil { log.Fatal(err) } }
在代码示例中,我们使用 ioutil.ReadFile
读取源文件的内容,并使用 ioutil.WriteFile
将数据写入目标文件。
Go 列出文件
filepath.Walk
遍历文件树,为树中的每个文件或目录(包括根目录)调用指定的函数。该函数会递归地遍历所有子目录。
package main import ( "fmt" "log" "os" "path/filepath" ) func main() { var files []string root := "/home/janbodnar/Documents" err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { fmt.Println(err) return nil } if !info.IsDir() && filepath.Ext(path) == ".txt" { files = append(files, path) } return nil }) if err != nil { log.Fatal(err) } for _, file := range files { fmt.Println(file) } }
在代码示例中,我们搜索扩展名为 .txt
的文件。
var files []string
匹配的文件存储在 files
切片中。
root := "/home/janbodnar/Documents"
这是我们开始搜索的根目录。
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
filepath.Walk
的第一个参数是根目录。第二个参数是 walk 函数;filepath.Walk
调用该函数来访问每个文件或目录。
if err != nil { fmt.Println(err) return nil }
如果出错,则打印错误,但继续在其他地方搜索。
if !info.IsDir() && filepath.Ext(path) == ".txt" { files = append(files, path) }
如果文件不是目录且具有 .txt
扩展名,我们将其追加到 files
切片。
for _, file := range files { fmt.Println(file) }
最后,我们遍历 files
切片并将所有匹配的文件打印到控制台。
来源
在本文中,我们处理了 Golang 中的文件。