2012-04-23 28 views
15

Tôi cần đọc một tệp văn bản được mã hóa trong GBK. Thư viện chuẩn trong ngôn ngữ lập trình Go giả định rằng tất cả văn bản được mã hóa bằng UTF-8.Đọc một tập tin văn bản không phải UTF-8 ở số

Làm cách nào để đọc tệp trong các mã hóa khác?

+0

Tại sao lại là downvotes? –

+0

Điều này giống như một câu hỏi rất hợp lý và rõ ràng, bỏ phiếu để mở lại (ngay cả ở dạng ban đầu) – OscarRyz

Trả lời

13

Trước đây (như được đề cập trong câu trả lời cũ hơn) cách "dễ dàng" để thực hiện việc này liên quan đến các gói bên thứ ba cần cgo và gói thư viện iconv. Đó là điều không mong muốn vì nhiều lý do. Rất may, trong một thời gian dài đã có một cấp trên tất cả đi cách làm điều này bằng cách sử dụng chỉ gói được cung cấp bởi các tác giả đi (không phải trong bộ chính của gói nhưng trong Go Sub-Repositories).

Gói golang.org/x/text/encoding xác định giao diện cho mã hóa ký tự chung có thể chuyển đổi thành/từ UTF-8. Gói phụ golang.org/x/text/encoding/simplifiedchinese cung cấp GB18030, GBKHZ-GB2312 triển khai mã hóa.

Dưới đây là ví dụ về đọc và viết tệp được mã hóa GBK. Lưu ý rằng io.Readerio.Writer thực hiện mã hóa "khi đang di chuyển" khi dữ liệu đang được đọc/ghi.

package main 

import (
    "bufio" 
    "fmt" 
    "log" 
    "os" 

    "golang.org/x/text/encoding/simplifiedchinese" 
    "golang.org/x/text/transform" 
) 

// Encoding to use. Since this implements the encoding.Encoding 
// interface from golang.org/x/text/encoding you can trivially 
// change this out for any of the other implemented encoders, 
// e.g. `traditionalchinese.Big5`, `charmap.Windows1252`, 
// `korean.EUCKR`, etc. 
var enc = simplifiedchinese.GBK 

func main() { 
    const filename = "example_GBK_file" 
    exampleWriteGBK(filename) 
    exampleReadGBK(filename) 
} 

func exampleReadGBK(filename string) { 
    // Read UTF-8 from a GBK encoded file. 
    f, err := os.Open(filename) 
    if err != nil { 
     log.Fatal(err) 
    } 
    r := transform.NewReader(f, enc.NewDecoder()) 

    // Read converted UTF-8 from `r` as needed. 
    // As an example we'll read line-by-line showing what was read: 
    sc := bufio.NewScanner(r) 
    for sc.Scan() { 
     fmt.Printf("Read line: %s\n", sc.Bytes()) 
    } 
    if err = sc.Err(); err != nil { 
     log.Fatal(err) 
    } 

    if err = f.Close(); err != nil { 
     log.Fatal(err) 
    } 
} 

func exampleWriteGBK(filename string) { 
    // Write UTF-8 to a GBK encoded file. 
    f, err := os.Create(filename) 
    if err != nil { 
     log.Fatal(err) 
    } 
    w := transform.NewWriter(f, enc.NewEncoder()) 

    // Write UTF-8 to `w` as desired. 
    // As an example we'll write some text from the Wikipedia 
    // GBK page that includes Chinese. 
    _, err = fmt.Fprintln(w, 
     `In 1995, China National Information Technology Standardization 
Technical Committee set down the Chinese Internal Code Specification 
(Chinese: 汉字内码扩展规范(GBK); pinyin: Hànzì Nèimǎ 
Kuòzhǎn Guīfàn (GBK)), Version 1.0, known as GBK 1.0, which is a 
slight extension of Codepage 936. The newly added 95 characters were not 
found in GB 13000.1-1993, and were provisionally assigned Unicode PUA 
code points.`) 
    if err != nil { 
     log.Fatal(err) 
    } 

    if err = f.Close(); err != nil { 
     log.Fatal(err) 
    } 
} 
5

Hãy thử go-iconv. Nó kết thúc tốt đẹp iconv và thực hiện io.Readerio.Writer.

Điều này message trong nhóm thảo luận golang-china đang đề cập đến một vài ví dụ về việc sử dụng go-iconv.

+0

Một tùy chọn khác là đọc tệp dưới dạng một đốm màu đục thành bộ đệm và sau đó giải thích nó dưới dạng văn bản trong một mã hóa cụ thể sử dụng [go-charset] (http://code.google.com/p/go-charset); xem [câu hỏi này] (http://stackoverflow.com/q/10039701/720999) để biết thêm thông tin. Tôi đã không nhìn vào mã, nhưng nó xuất hiện để hỗ trợ một tập hợp các bộ mã/bảng mã kế thừa được sử dụng nhiều nhất, gói này không cần iconv mà có thể là một lợi thế. – kostix

+0

@kostix Từ thông tin trên trang tiêu đề của http://code.google.com/p/go-charset có vẻ như trong trường hợp gbk, gói sử dụng thư viện biểu tượng GNU. –

+0

Gói này cũng có thể được sử dụng để thực hiện chuyển đổi: https://godoc.org/golang.org/x/text/encoding – OscarRyz

Các vấn đề liên quan