Re:Go 운영 csv의 기본 사항
개시하다
Print 표준을 통해 내보내면 다음과 같이 표시됩니다.(SHIFT-JIS 형식이기 때문에 맥에서 봤을 때 난사이즈예요. 잠시 틀어놓을게요.)
일본에서 CSV 파일은 일반적으로 ShiftJIS에서 자주 인코딩됩니다.Go 언어의 내부 인코딩은 UTF-8이므로 ShiftJIS의 CSV 파일을 읽으면 코드가 흐려집니다.
저기 편한 건요.
인코딩의 변환
golang.org/x/text/transform
이 편리합니다.이 포장과golang.org/x/text/encoding/japanese
를 사용하면 os.Open
에서 열린 파일도 UTF-8처럼 처리할 수 있다.어떻게 처리합니까
japanese
포장에 변수japanese.ShiftJIS
, 변수japanese.EUCJP
와 변수japanese.ISO2022JP
를 발표했다.이 인터페이스들은 실현되었다encoding.Encoding
.// Encoding is a character set encoding that can be transformed to and from
// UTF-8.
type Encoding interface {
// NewDecoder returns a Decoder.
NewDecoder() *Decoder
// NewEncoder returns an Encoder.
NewEncoder() *Encoder
}
Enceoder와Decorder는 바이트열을 바꾸는 방법Encode
과 Decode
이 있다.func (d *Decoder) Bytes(b []byte) ([]byte, error) {
b, _, err := transform.Bytes(d, b)
if err != nil {
return nil, err
}
return b, nil
}
func (e *Encoder) Bytes(b []byte) ([]byte, error) {
b, _, err := transform.Bytes(e, b)
if err != nil {
return nil, err
}
return b, nil
}
가 이 디코더를 사용하여 생성io.Reader
한 것은transform.NewReader
이다.구체적으로 다음과 같이 ShiftJIS 전용io.Reader
을 제작할 수 있다.transform.NewReader(f, japanese.ShiftJIS.NewDecoder())
원문의 CSV를 읽은 경우 다음과 같이 실시할 수 있다.package main
import (
"encoding/csv"
"fmt"
"log"
"os"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/transform"
)
func main() {
f, err := os.Open("28HYOGO.CSV")
if err != nil {
log.Fatal(err)
}
defer f.Close()
r := csv.NewReader(transform.NewReader(f, japanese.ShiftJIS.NewDecoder()))
for {
records, err := r.Read()
if err != nil {
log.Fatal(err)
}
fmt.Println(records)
}
}
간단하네요.저는 Go의 흐름 방향을 좋아해요.
내가 처음에 Go에 흥미를 느낀 것은 Go가 흐름을 방향으로 하기 때문이다.파일에서 모든 내용을 읽고 바이트열에 전달하여 CSV를 제거하는 프로그램 라이브러리도 볼 수 있지만 메모리가 낭비됩니다.Go는 흐름을 향하기 때문에
io.Reader
를 사용하여 입력을 효과적으로 처리할 수 있다.예를 들어, 위의 소스 코드인 경우 CSV 파일의 행 수가 아무리 길어도 메모리가 부족하지 않습니다.
이것이 바로 내가 Go를 좋아하는 이유다.
encoding/json
마찬가지로 입력이 io.Reader
라는 것을 주목하는 사람도 있을 수 있다.그래도 zip을 읽으면 되지 않을까요?
네.Go에는
archive/zip
가 있으므로 zip 파일이 확장되지 않고 CSV를 읽을 수 있습니다.package main
import (
"archive/zip"
"encoding/csv"
"fmt"
"log"
"path/filepath"
"strings"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/transform"
)
func readCSV(file *zip.File) error {
r, err := file.Open()
if err != nil {
return err
}
defer r.Close()
cr := csv.NewReader(transform.NewReader(r, japanese.ShiftJIS.NewDecoder()))
for {
records, err := cr.Read()
if err != nil {
return err
}
fmt.Println(records)
}
}
func main() {
zf, err := zip.OpenReader("28hyogo.zip")
if err != nil {
log.Fatal(err)
}
defer zf.Close()
for _, file := range zf.File {
if strings.ToLower(filepath.Ext(file.Name)) != ".csv" {
continue
}
err := readCSV(file)
if err != nil {
log.Fatal(err)
}
}
}
끝말
이런 깊은 밤에 Go가 흐르는 지점을 전달하려고 써봤기 때문이다.메모리 효율이 좋은 처리를 반드시 실현해야 한다.
Reference
이 문제에 관하여(Re:Go 운영 csv의 기본 사항), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mattn/articles/fd545a14b0ffdf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)