Golang读取UTF-8文本文件的方法

Golang读取UTF-8文本文件的方法 早上好, 在读取UTF-8格式的文本文件时,该文件的第一个位置会读取到一个问号(“?”)。这对于任何UTF-8格式的文本文件都会发生。 我想知道为什么会发生这种情况,以及我应该如何解决这个问题。

2 回复

这很可能是字节顺序标记。

不过很难具体说明,因为我不确定你是如何检查读取到的内容的。

唯一有效的方法是检查字节,而不是字形/字素。

更多关于Golang读取UTF-8文本文件的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在读取UTF-8文本文件时出现开头的问号,通常是因为文件包含BOM(字节顺序标记)。UTF-8的BOM是三个字节:0xEF 0xBB 0xBF,当这些字节被当作普通文本字符读取时,可能会显示为问号或其他乱码。

以下是两种常见的解决方法:

1. 使用bufio.Scanner并跳过BOM

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        panic(err)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    if scanner.Scan() {
        line := scanner.Text()
        // 移除UTF-8 BOM
        line = string(bytes.TrimPrefix([]byte(line), []byte{0xEF, 0xBB, 0xBF}))
        fmt.Println(line)
    }
    
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

2. 使用ioutil.ReadFile并处理BOM

package main

import (
    "fmt"
    "io/ioutil"
    "strings"
)

func main() {
    content, err := ioutil.ReadFile("example.txt")
    if err != nil {
        panic(err)
    }
    
    // 移除UTF-8 BOM
    content = bytes.TrimPrefix(content, []byte{0xEF, 0xBB, 0xBF})
    
    text := string(content)
    lines := strings.Split(text, "\n")
    for _, line := range lines {
        fmt.Println(line)
    }
}

3. 使用unicode/utf8包检测BOM

package main

import (
    "fmt"
    "io/ioutil"
    "unicode/utf8"
)

func main() {
    content, err := ioutil.ReadFile("example.txt")
    if err != nil {
        panic(err)
    }
    
    // 检查并移除BOM
    if len(content) >= 3 && content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF {
        content = content[3:]
    }
    
    // 验证UTF-8编码
    if !utf8.Valid(content) {
        fmt.Println("文件包含无效的UTF-8编码")
        return
    }
    
    fmt.Println(string(content))
}

4. 使用golang.org/x/text/encoding/unicode包(第三方)

package main

import (
    "fmt"
    "io/ioutil"
    "golang.org/x/text/encoding/unicode"
    "golang.org/x/text/transform"
)

func main() {
    content, err := ioutil.ReadFile("example.txt")
    if err != nil {
        panic(err)
    }
    
    // 自动检测并移除BOM
    decoder := unicode.UTF8BOM.NewDecoder()
    decoded, _, err := transform.Bytes(decoder, content)
    if err != nil {
        panic(err)
    }
    
    fmt.Println(string(decoded))
}

第一种方法适用于逐行读取大文件,第二种方法适合读取小文件,第三种方法提供了更严格的UTF-8验证,第四种方法使用第三方库自动处理BOM。选择哪种方法取决于具体的应用场景和文件大小。

回到顶部