如何在 Golang 中逐字阅读文件?
文件读取是编程语言的一个重要方面。我们需要以编程方式执行某些操作,在文件读/写中使用自动化使我们能够创建某些原本看起来不可能的程序/项目。
文件输入
要处理文件,我们必须在读取文件时输入现有文件。我们当然可以通过使用文件名来获取输入,但在这里我们将其简单化并从预定义的文件中读取。我们可以使用 Golang 中的 os 包/模块打开文件进行读取。 os 包中的 Open函数让我们将文件名作为参数提供给它。
Go
// Golang program to open file
package main
import (
"os"
"log"
)
func main() {
file, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
}
Go
// Golang program to scan files
package main
import (
"fmt"
"os"
"log"
"bufio"
)
func main() {
file, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}else{
fmt.Println(file)
}
Scanner := bufio.NewScanner(file)
Scanner.Split(bufio.ScanWords)
fmt.Println(Scanner)
}
Go
// Go program to scan the words
package main
import (
"fmt"
"os"
"bufio"
"log"
)
func main() {
file, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
Scanner := bufio.NewScanner(file)
Scanner.Split(bufio.ScanWords)
for Scanner.Scan() {
fmt.Println(Scanner.Text())
}
if err := Scanner.Err(); err != nil {
log.Fatal(err)
}
}
Go
// Go program to append to a String slice
package main
import (
"fmt"
"os"
"bufio"
"log"
)
func main() {
file, err := os.Open("sample.txt")
var words []string
if err != nil {
log.Fatal(err)
}
Scanner := bufio.NewScanner(file)
Scanner.Split(bufio.ScanWords)
for Scanner.Scan() {
words = append(words, Scanner.Text())
}
fmt.Println(words)
for _, word := range words {
fmt.Println(word)
}
if err := Scanner.Err(); err != nil {
log.Fatal(err)
}
}
Open函数要么返回对文件的指针引用,要么在找不到文件、无法打开以供读取等情况下返回错误。因此,我们存储任何适用的值。如果我们有错误,我们只想将错误记录为致命错误并通过 Go 中的 log 包退出程序。
输出:
&{0x11934420}
使用 bufio 扫描文件
要真正从文件指针中获取内容,我们需要使用 Scanner 函数,这些函数字符(符文)等读取文件内容的功能。
在此之前,我们需要一个 Reader 从流中读取,我们使用 NewScanner函数,它将参数作为流接收。当我们要从文件中读取数据时,我们会将文件指针解析为参数。这将创建一个可以从提供的文件中读取的扫描器。
在我们初始化扫描器之后,我们可以提供一个拆分器(拆分函数)或一种将根据特定模式读取的格式。由于我们要逐字阅读,我们将解析 bufio.ScanWords函数。此函数充当给定流的拆分器,即,它将整个文件拆分为在我们的例子中提供的拆分函数为单词。
去
// Golang program to scan files
package main
import (
"fmt"
"os"
"log"
"bufio"
)
func main() {
file, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}else{
fmt.Println(file)
}
Scanner := bufio.NewScanner(file)
Scanner.Split(bufio.ScanWords)
fmt.Println(Scanner)
}
输出:
&{0x11864420}
&{0x118061a8 0x48e410 65536 [] [] 0 0 0 false false}
因此,使用 bufio Scanner 及其相关功能,如 NewScanner、Split 和 ScanWords,我们可以设置文件扫描器。我们现在可以从扫描仪中读取文件中的每个单词。
扫描词
为了遍历文件,我们创建了扫描仪,有关文件的所有信息都存储在 Scanner 中。我们可以使用另一个名为 Scan 的函数来访问文件的内容。此函数将扫描器推进到下一个拆分令牌。因此,如果扫描器中有内容/令牌,它将返回 true,否则,如果我们到达文件末尾,则返回 false,但是当它是 EOF 时,错误消息为 nil,因此我们在没有任何有效错误的情况下退出。在循环内部,我们可以使用函数Text。这个函数返回最近分配的扫描器的字节,在我们的例子中它是我们提供的文件。所以它基本上获取了 Scan函数正在迭代的当前令牌的文本。因此我们可以打印 Text函数返回的值。
去
// Go program to scan the words
package main
import (
"fmt"
"os"
"bufio"
"log"
)
func main() {
file, err := os.Open("sample.txt")
if err != nil {
log.Fatal(err)
}
Scanner := bufio.NewScanner(file)
Scanner.Split(bufio.ScanWords)
for Scanner.Scan() {
fmt.Println(Scanner.Text())
}
if err := Scanner.Err(); err != nil {
log.Fatal(err)
}
}
正如我们所见,我们能够逐字迭代文件。使用 err 变量进行错误检查,我们首先将错误存储在变量 err 中,然后当且仅当 err 不为零时才被视为错误,并且在记录错误后我们退出程序。在我们评估条件之前,分号(;)用于链接 go lang 中的语句。
附加到字符串切片
我们只是逐字打印文件内容,这可能不是包的一个好的用例。我们甚至可以以切片的形式存储上下文,在这种情况下,每个元素都是一个单词的字符串切片。
去
// Go program to append to a String slice
package main
import (
"fmt"
"os"
"bufio"
"log"
)
func main() {
file, err := os.Open("sample.txt")
var words []string
if err != nil {
log.Fatal(err)
}
Scanner := bufio.NewScanner(file)
Scanner.Split(bufio.ScanWords)
for Scanner.Scan() {
words = append(words, Scanner.Text())
}
fmt.Println(words)
for _, word := range words {
fmt.Println(word)
}
if err := Scanner.Err(); err != nil {
log.Fatal(err)
}
}
这段代码中改变的只是我们追加和迭代创建的字符串切片的方式。我们首先通过语法名称 [] 字符串初始化一个字符串切片,在初始化 Scanner 并使用 Scan函数进行迭代之后,我们只需将Scanner.Text()函数返回的值附加到字符串切片中。我们可以打印切片或对其进行迭代并对其进行所需的处理。这就是我们如何将文件的内容逐字附加到 Golang 中的字符串切片的方法。