使用Golang扫描文本文件中的单词

使用Golang扫描文本文件中的单词 我想将一个文本文件(file.txt)分割成两个大小相等的独立文本文件,例如 file1.txt 和 file2.txt。我的分割策略是扫描单词并计数,然后将前一半单词写入 file1.txt,剩余的写入 file2.txt。代码如下:

package main
import (
    "bufio"
    "fmt"
    "log"
    "os"
)
func main() {
    WordbyWordScan()
}
func WordbyWordScan() {
    file, err := os.Open("file.txt.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()
    scanner := bufio.NewScanner(file)
    scanner.Split(bufio.ScanWords)
    count := 0
    for scanner.Scan() {
        fmt.Println(scanner.Text())
        count++
    }
    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%d\n", count)
}

据我猜测,scanner.Scan() 返回一个布尔值。在统计完单词数量后,我该如何在 Golang 中实现这样的代码,将前一半单词写入 file1.txt,剩余的写入 file2.txt?


更多关于使用Golang扫描文本文件中的单词的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

stackoverflow.com

使用Golang扫描文本文件中的单词

标签: go, text, word, scanning

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    // 打开文件
    file, err := os.Open("input.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    // 创建一个扫描器来读取文件
    scanner := bufio.NewScanner(file)

    // 设置扫描器的分割函数为按单词分割
    scanner.Split(bufio.ScanWords)

    // 循环扫描每个单词
    for scanner.Scan() {
        // 获取当前单词并转换为小写
        word := strings.ToLower(scanner.Text())
        // 在此处理单词,例如打印或计数
        fmt.Println(word)
    }

    // 检查扫描过程中是否有错误
    if err := scanner.Err(); err != nil {
        panic(err)
    }
}

更多关于使用Golang扫描文本文件中的单词的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


要实现将单词按数量等分写入两个文件,可以先将所有单词读取到内存中,然后根据计数进行分割。以下是修改后的代码:

package main

import (
    "bufio"
    "log"
    "os"
)

func main() {
    WordbyWordScan()
}

func WordbyWordScan() {
    // 读取源文件
    file, err := os.Open("file.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // 扫描单词
    scanner := bufio.NewScanner(file)
    scanner.Split(bufio.ScanWords)
    
    // 存储所有单词
    var words []string
    for scanner.Scan() {
        words = append(words, scanner.Text())
    }
    
    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }

    totalWords := len(words)
    if totalWords == 0 {
        return
    }

    // 计算分割点
    splitIndex := totalWords / 2

    // 写入第一个文件
    file1, err := os.Create("file1.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file1.Close()
    
    writer1 := bufio.NewWriter(file1)
    for i := 0; i < splitIndex; i++ {
        writer1.WriteString(words[i])
        if i < splitIndex-1 {
            writer1.WriteString(" ")
        }
    }
    writer1.Flush()

    // 写入第二个文件
    file2, err := os.Create("file2.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file2.Close()
    
    writer2 := bufio.NewWriter(file2)
    for i := splitIndex; i < totalWords; i++ {
        writer2.WriteString(words[i])
        if i < totalWords-1 {
            writer2.WriteString(" ")
        }
    }
    writer2.Flush()
}

如果文件很大,不想将所有单词加载到内存中,可以使用流式处理:

package main

import (
    "bufio"
    "io"
    "log"
    "os"
)

func main() {
    StreamWordSplit()
}

func StreamWordSplit() {
    // 打开源文件
    file, err := os.Open("file.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // 第一次扫描统计单词总数
    scanner1 := bufio.NewScanner(file)
    scanner1.Split(bufio.ScanWords)
    wordCount := 0
    for scanner1.Scan() {
        wordCount++
    }
    
    if err := scanner1.Err(); err != nil {
        log.Fatal(err)
    }

    if wordCount == 0 {
        return
    }

    // 重置文件指针
    file.Seek(0, io.SeekStart)

    // 第二次扫描处理分割
    scanner2 := bufio.NewScanner(file)
    scanner2.Split(bufio.ScanWords)
    
    // 创建输出文件
    file1, err := os.Create("file1.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file1.Close()
    
    file2, err := os.Create("file2.txt")
    if err != nil {
        log.Fatal(err)
    }
    defer file2.Close()

    writer1 := bufio.NewWriter(file1)
    writer2 := bufio.NewWriter(file2)
    
    currentCount := 0
    splitIndex := wordCount / 2
    
    for scanner2.Scan() {
        word := scanner2.Text()
        
        if currentCount < splitIndex {
            writer1.WriteString(word)
            if currentCount < splitIndex-1 {
                writer1.WriteString(" ")
            }
        } else {
            writer2.WriteString(word)
            if currentCount < wordCount-1 {
                writer2.WriteString(" ")
            }
        }
        currentCount++
    }
    
    writer1.Flush()
    writer2.Flush()
    
    if err := scanner2.Err(); err != nil {
        log.Fatal(err)
    }
}

第一个方案适合文件较小的情况,将所有单词读入内存后处理。第二个方案通过两次文件扫描,避免了内存占用过高的问题,适合处理大文件。两个方案都保持了单词间的空格分隔。

回到顶部