2012-04-23 7 views
15

Necesito leer un archivo de texto codificado en GBK. La biblioteca estándar en el lenguaje de programación Go asume que todo el texto está codificado en UTF-8.Lectura de un archivo de texto que no sea UTF-8 en Ir

¿Cómo puedo leer archivos en otras codificaciones?

+0

¿Por qué los votos a favor? –

+0

Esto parece una pregunta muy razonable y clara, votando para volver a abrir (incluso en su forma original) – OscarRyz

Respuesta

13

Anteriormente (como se menciona en una respuesta anterior), la forma "fácil" de hacerlo consistía en utilizar paquetes de terceros que necesitaban cgo y envolvían la biblioteca de iconv. Eso es indeseable por muchas razones. Afortunadamente, desde hace bastante tiempo ha habido una forma superior de ir a todos al usar solo paquetes proporcionados por los autores de Go (no en el conjunto principal de paquetes, sino en el Go Sub-Repositories).

El paquete golang.org/x/text/encoding define una interfaz para codificaciones genéricas de caracteres que pueden convertirse a/desde UTF-8. El subpaquete golang.org/x/text/encoding/simplifiedchinese proporciona GB18030, GBK y HZ-GB2312 implementaciones de codificación.

Aquí hay un ejemplo de cómo leer y escribir un archivo codificado en GBK. Tenga en cuenta que io.Reader y io.Writer hacen la codificación "sobre la marcha" mientras se leen/escriben los datos.

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

Probar go-iconv. Envuelve iconv e implementa io.Reader y io.Writer.

Este message en el grupo de discusión golang-china menciona algunos ejemplos del uso de go-iconv.

+0

Otra opción sería leer el archivo como un blob opaco en un búfer y luego interpretarlo como texto en una codificación particular utilizando [go-charset] (http://code.google.com/p/go-charset); vea [esta pregunta] (http://stackoverflow.com/q/10039701/720999) para más información. No miré el código, pero parece que para admitir un conjunto de conjuntos de caracteres/codificaciones heredados más utilizados, este paquete no necesita iconv, lo que podría ser una ventaja. – kostix

+0

@kostix De la información en la página de título de http://code.google.com/p/go-charset, parece que en el caso de gbk, el paquete usa la biblioteca GNU iconv. –

+0

Este paquete también se puede usar para realizar la transformación: https://godoc.org/golang.org/x/text/encoding – OscarRyz

Cuestiones relacionadas