2012-04-23 10 views
15

GBKでエンコードされたテキストファイルを読む必要があります。 Goプログラミング言語の標準ライブラリは、すべてのテキストがUTF-8でエンコードされていることを前提としています。Goで非UTF-8テキストファイルを読む

他のエンコーディングでファイルを読むにはどうすればよいですか?

+0

なぜdownvotesですか? –

+0

これは非常に合理的ではっきりした質問のように見えます(元の形式でさえも)再度開いて投票します – OscarRyz

答えて

13

これまでの(簡単な方法で)cgoが必要なサードパーティのパッケージを使用し、iconvライブラリをラップしていました。それは多くの理由から望ましくないことです。ありがたいことに、しばらくの間、Go Authors(パッケージのメインセットではなく、Go Sub-Repositories)によって提供されたパッケージのみを使用してこれを実行する優れたGoメソッドがありました。

golang.org/x/text/encodingパッケージでは、UTF-8との間で変換できる汎用文字エンコード用のインターフェイスが定義されています。 golang.org/x/text/encoding/simplifiedchineseサブパッケージは、GB18030,GBKおよびHZ-GB2312の実装を提供します。

次に、GBKでエンコードされたファイルを読み書きする例を示します。 io.Readerio.Writerは、データが読み書きされているときに「オンザフライ」でエンコードします。

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

お試しgo-iconviconvをラップし、io.Readerio.Writerを実装しています。

このmessageは、ゴランチャイナディスカッショングループで、go-iconvの使用例をいくつか挙げています。

+0

もう一つのオプションは、ファイルを不透明なブロブとしてバッファに読み込み、それを特定のエンコーディングのテキストとして解釈することです[go-charset](http://code.google.com/p/go-charset)を使用します。詳細については、[この質問](http://stackoverflow.com/q/10039701/720999)を参照してください。私はコードを見ませんでしたが、最もよく使われているレガシー文字セット/エンコーディングのセットをサポートするように見えますが、このパッケージはiconvを必要としません。 – kostix

+0

@kostix http://code.google.com/p/go-charsetのタイトルページの情報から、gbkの場合、パッケージはGNU iconvライブラリを使用しているようです。 –

+0

このパッケージを使用して、変換を実行することもできます:https://godoc.org/golang.org/x/text/encoding – OscarRyz

関連する問題