📜  如何在 Golang 中逐字阅读文件?

📅  最后修改于: 2022-05-13 01:55:26.503000             🧑  作者: Mango

如何在 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)
    }
}

如何在 Golang 中逐字阅读文件?

正如我们所见,我们能够逐字迭代文件。使用 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 中的字符串切片的方法。