介绍
在该系列的第22篇文章中,我们将研究Golang的文件处理过程,在接下来的几个帖子中,我们将使用Golang介绍文件的操作。在文件处理子系列的第一个条目中,我们将了解使用文件的READ
操作。我们将看到读取文件的不同方法,它可以是单词,逐行,甚至是块自定义的切换。
在处理文件时,我们还将使用标准库软件包,例如os
,bufio
等。我们还将介绍如何从远程位置读取文件。使用Golang,我们将与文件管理有低级的交互,但Golang还为我们提供了大部分繁重的文件和管理,因此使用文件变得很容易。
将文件读为单个字符串(使用OS.ReadFile)
我们可以使用Golang的os软件包,在该软件包中我们可以访问ReadFile Funciton。 ReadFile
函数将参数作为字符串作为字符串,它应为文件名,它返回一个字节或错误。我们已经讨论了该系列上一部分中的错误处理。因此,我们必须使用逗号OK错误语法来从Funciton获取适当的返回值。我们可以将字节的切片作为我们想要的文本或错误,如果存在错误,它是一个文件夹等。
package main
import (
"os"
"log"
)
func main() {
text, err := os.ReadFile("sample.txt")
if err != nil {
log.Fatal(err)
}
log.Println(string(text))
}
$ go run main.go
2022/10/23 22:39:11 Golang is a programming language.
created: 2007
type:static
因此,在这里的引擎盖下,我们有文本作为字节片。我们可以在文本上以切片的形式迭代文本,并通过字符中的字符在文件的内容中获取字符。尽管我们没有直接与文件内容进行交互,但我们将其存储在变量中。用技术词,文件直接直接加载到内存中。因此,我们返回包含文件内容的单个字符串对象。
按行读取文件
我们甚至可以逐行读取文件。使用bufio.NewScanner(),该函数在我们的情况下接收一个Reader对象,它将是一个文件对象。该函数返回一个扫描仪对象,该对象可用于使用特定的扫描仪方法读取文本。可以在循环中使用返回的对象对内容进行迭代,在我们的情况下,我们使用Scan方法将文件分为线。但是,我们可以使用其他方法来扫描单词,例如字符扫描字符的ScanRunes,ScanBytes进行字节扫描字节。
package main
import (
"bufio"
"log"
"os"
)
func main() {
f, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
line_list := []string{}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
line_list = append(line_list, line)
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
for _, line := range line_list {
log.Println(line)
}
}
$ go run line.go
2022/10/23 22:39:50 Golang is a programming language.
2022/10/23 22:39:50 created: 2007
2022/10/23 22:39:50 type:static
在上面的示例中,用bufio.NewScanner
读取文件,并借助Scan
函数划线。该行中的文本被扫描并存储在一个字符串的变量line
中,这进一步将其附加到字符串slice line_list
上。因此,我们可以按行迭代文件内容,并将结果存储为字符串数组。
在这里,我们在调用f.Close()
方法之前已经使用了defer
关键字,因为我们要在文件上执行操作后关闭文件。延期将在主函数的末尾(即在程序末尾)调用该函数。
通过定界符读取文件
我们甚至可以使用自定义定界符读取文件,该文件可用于读取CSV或其他定界符。 csv软件包具有一个NewReader函数,该功能接收到文件内容的对象,并且它将返回Reader对象。我们可以更改Reader
对象中的属性Comma
,并将其设置为我们想要的任何值作为定界符。此后,我们可以根据您的标准阅读整个内容或将其读取为单词,线条,字节或块。提取的内容将被分为由Comma
属性中的定界符设置的数据切片。
package main
import (
"encoding/csv"
"log"
"os"
)
func main() {
f, err := os.Open("delimeter.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
reader := csv.NewReader(f)
reader.Comma = ':'
data, err := reader.ReadAll()
if err != nil {
log.Fatal(err)
}
log.Println(data)
}
$ cat delimiter.txt
10:22:2022
golang:21:read
$ go run delimiter.go
2022/10/23 22:40:44 [[10 22 2022] [golang 21 read]]
在上面的示例中,定界符设置为:
,因此通过使用Comma
属性,我们可以设置定界符。通过使用NewReader
函数,我们可以获取读取器对象并使用与读取器对象关联的ReadAll
函数,我们读取内容。内容被作为字符串片获取,该字符串将被定界符分开。
用字读文件
我们甚至可以使用ScanWords读单词。单词可以是由空间分开的字符集合。该功能没有按线读取该功能,而是在空间之后读取文件内容。
package main
import (
"bufio"
"log"
"os"
)
func main() {
f, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanWords)
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
wordlist := []string{}
for scanner.Scan() {
word := scanner.Text()
wordlist = append(wordlist, word)
log.Println(word)
}
log.Println(wordlist)
}
$ go run word.go
2022/10/23 22:42:03 Golang
2022/10/23 22:42:03 is
2022/10/23 22:42:03 a
2022/10/23 22:42:03 programming
2022/10/23 22:42:03 language.
2022/10/23 22:42:03 created:
2022/10/23 22:42:03 2007
2022/10/23 22:42:03 type:static
2022/10/23 22:42:03 [Golang is a programming language. created: 2007 type:static]
使用ScanWords
函数,我们可以通过Word读取文件的内容。具有文件的实际内容的扫描仪对象由Split
函数拆分,拆分标准用作单词,其中定界符将用作空间。 wordlist
是我们附加字符串的一片字符串,依次从scanner.Text()
函数读取。
在块中读取文件
我们甚至可以在块中读取文件,块是字节的集合/数组。我们可以指定要在一个GO中读取的字节数,并且文件读取器将扫描内容作为每次迭代数量的片段。 Read funciton接收一小部分字节,并将返回读取器对象中的字节数。
package main
import (
"bufio"
"io"
"log"
"os"
)
func main() {
f, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
reader := bufio.NewReader(f)
chunk_size := 16
chunk_list := []string{}
buf := make([]byte, chunk_size)
for {
n, err := reader.Read(buf)
if err != nil {
if err != io.EOF {
log.Fatal(err)
}
break
}
chunk_list = append(chunk_list, string(buf[0:n]))
}
for _, chunk := range chunk_list {
log.Print(chunk)
}
}
$ go run chunks.go
2022/10/23 22:44:41 Golang is a prog
2022/10/23 22:44:41 ramming language
2022/10/23 22:44:41 .
created: 2007
2022/10/23 22:44:41 type:static
在上面的示例中,我们打开了文件,并将内容加载到f
变量中。借助NewReader
函数读取内容,该功能返回读取器对象,该对象可以进一步用于将内容读取到字节的块中。 chunk_size
定义了我们要用于读取内容的大小,chunk_list
是一片字符串,将块/字节的切片作为类型的种姓将其固定在一片字符串中。使用Read
函数,将读取字节到该函数中,并根据Read
函数中获得的块大小分配缓冲区。我们将字节的切片附加到切片阵列中,从而获得字符串的切片。
通过字符读取文件字符
我们甚至可以使用ScanRunes函数一次读取每个字符,此函数一次扫描单个符文/字节。因此,我们可以一次扫描这些符文并将它们存储为一片字节。因此,我们将将文件的内容存储为一个字节片。
package main
import (
"bufio"
"log"
"os"
)
func main() {
f, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanRunes)
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
charlist := []byte{}
for scanner.Scan() {
char := byte(scanner.Text()[0])
charlist = append(charlist, char)
}
log.Println(charlist)
}
$ go run char.go
2022/10/23 22:48:55 [71 111 108 97 110 103 32 105 115 32 97 32 112 114 111 103 114 97 109 109 105 110 103 32 108 97 110 103 117 97 103 101 46 10 99 114 101 97 116 101 100 58 32 50 48 48 55 10 116 121 112 101 58 115 116 97 116 105 99 10]
我们可以在上面的示例中看到,输出是一个字节片,因此它们是uint8
,我们可以将它们投射到string
并获得字节的等效ASCII表示。 ScanRunes
函数允许我们将读取器对象分配到单元字节/runes时,将读者对象的内容读取为符文。
就是这部分。所有代码示例和命令的参考可以在100 days of Golang GitHub存储库中找到。
结论
在本节中,我们探索了与文件读数相关的功能和软件包。我们看到了如何使用os
,bufio
,encoding
等的软件包来以不同的方式读取文件。我们看到了如何将文件读成单个字符串,逐行,单词,字符,ckalne,in concunks in lord word,以及自定义定界符。希望文件阅读的基础知识将被清除,并且有了示例,就可以理解句法结构。
感谢您的阅读。如果您有任何疑问,问题或反馈,可以在下面的讨论中或我的社交手柄上告诉我。快乐编码:)系列:“ [''100天Golang']