解析csv文件时的奇怪输出

解析csv文件时的奇怪输出,csv,go,encoding,utf-16,Csv,Go,Encoding,Utf 16,我正在用golang解析google api中的一个csv文件,该文件以utf-16编码,下面的代码尝试读取一个recordskip头并打印记录,但它给了我这样的输出,这很奇怪: , v=/09/20 00:35:42 k=Smartfren Andromax AD681H 我想这可能与utf-16编码有关,但不知道细节,以下是代码: 包干管 import ( "encoding/csv" "io" "log" "net/http" "strings"

我正在用golang解析google api中的一个csv文件,该文件以utf-16编码,下面的代码尝试读取一个recordskip头并打印记录,但它给了我这样的输出,这很奇怪:

, v=/09/20 00:35:42 k=Smartfren Andromax AD681H
我想这可能与utf-16编码有关,但不知道细节,以下是代码: 包干管

import (
    "encoding/csv"
    "io"
    "log"
    "net/http"
    "strings"
)

var url = "http://storage.googleapis.com/play_public/supported_devices.csv"

func main() {

    resp, err := http.Get(url)
    if err != nil {
        return
    }
    defer resp.Body.Close()

    r := csv.NewReader(resp.Body)
    r.LazyQuotes = true
    r.FieldsPerRecord = -1
    // skip header
    r.Read()

    m := make(map[string]string)
    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Println(err)
            continue
        }
        if len(record) >= 4 {
            m[strings.TrimSpace(record[3])] = strings.TrimSpace(record[1])
            for k, v := range m {
                log.Printf("k=%s, v=%s\n", k, v)
            }
            break
        }
    }
}

正如您所怀疑的,输入数据必须从UTF-16编码字符流转换为UTF-8编码字符流。您可以通过使用Go子存储库包来实现这一点:


正如您所怀疑的,输入数据必须从UTF-16编码字符流转换为UTF-8编码字符流。您可以通过使用Go子存储库包来实现这一点:

package main

import (
    "encoding/csv"
    "io"
    "log"
    "net/http"
    "strings"

    "golang.org/x/text/encoding/unicode"
)

var url = "http://storage.googleapis.com/play_public/supported_devices.csv"

func main() {

    resp, err := http.Get(url)
    if err != nil {
        return
    }
    defer resp.Body.Close()

    dec := unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder()
    reader := dec.Reader(resp.Body)

    r := csv.NewReader(reader)
    r.LazyQuotes = true
    r.FieldsPerRecord = -1
    // skip header
    r.Read()

    m := make(map[string]string)
    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Println(err)
            continue
        }
        if len(record) >= 4 {
            m[strings.TrimSpace(record[3])] = strings.TrimSpace(record[1])
            for k, v := range m {
                log.Printf("k=%s, v=%s\n", k, v)
            }
            break
        }
    }
}