Go文件教程展示了如何在Golang中处理文件。我们读取文件、写入文件、创建文件、列出文件并确定它们的大小和修改时间。
要在Go中处理文件,我们使用os、ioutil和fmt包。
os.Stat函数返回描述文件的FileInfo结构。
$ go version go version go1.18.1 linux/amd64
我们使用Go版本1.18。
检查文件是否存在
在下面的例子中,我们检查给定的文件是否存在。
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错误,则文件不存在。
去创建文件
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")
}
该示例创建一个空文件。
去删除文件
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)
}
我们使用ModTime函数从FileInfo结构中获取最后修改时间。
去读文件
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函数逐行前进。
去写文件
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方法将字符串写入文件。
追加到文件
为了追加到文件,我们将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文件。
去复制文件
下一个示例复制一个文件。
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将数据写入目标文件。
去列表文件
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中的文件。
列出所有Go教程。
