python - Go中如何改进文件编码转换

标签 python go encoding io character-encoding

我一直在处理一些必须转换为 UTF-8 的大文件,因为这些文件是巨大的传统工具,如 iconv 无法工作。所以我决定用 Go 编写自己的工具,但是我注意到这种编码转换在 Go 中非常慢。这是我的代码:

package main

import (
    "fmt"
    "io"
    "log"
    "os"

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

func main() {
    if len(os.Args) != 3 {
        fmt.Fprintf(os.Stderr, "usage:\n\t%s [input] [output]\n", os.Args[0])
        os.Exit(1)
    }

    f, err := os.Open(os.Args[1])

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

    out, err := os.Create(os.Args[2])

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

    r := charmap.ISO8859_1.NewDecoder().Reader(f)

    buf := make([]byte, 1048576)

    io.CopyBuffer(out, r, buf)

    out.Close()
    f.Close()
}

Python 中的类似代码性能更高:

import codecs
BLOCKSIZE = 1048576 # or some other, desired size in bytes
with codecs.open("FRWAC-01.xml", "r", "latin_1") as sourceFile:
    with codecs.open("FRWAC-01-utf8.xml", "w", "utf-8") as targetFile:
        while True:
            contents = sourceFile.read(BLOCKSIZE)
            if not contents:
                break
            targetFile.write(contents)

我确信我的 Go 代码会快得多,因为 Go 中的一般 I/O 很快,但事实证明它比 Python 代码慢得多。有没有办法改进 Go 程序?

最佳答案

这里的问题是您没有在两种情况下比较相同的代码。此外,Go 中的 IO 速度与 python 没有显着差异,因为它们进行相同的系统调用。

在python版本中,文件默认是缓冲的。在 Go 版本中,当您将 io.CopyBuffer1048576 字节缓冲区一起使用时,解码器将进行任何大小的 Read 调用它需要直接在未缓冲的文件上。

bufio 包装文件 IO 将产生类似的结果。

inFile, err := os.Open(os.Args[1])
if err != nil {
    log.Fatal(err)
}
defer inFile.Close()

outFile, err := os.Create(os.Args[2])
if err != nil {
    log.Fatal(err)
}
defer outFile.Close()

in := bufio.NewReaderSize(inFile, 1<<20)

out := bufio.NewWriterSize(outFile, 1<<20)
defer out.Flush()

r := charmap.ISO8859_1.NewDecoder().Reader(in)

if _, err := io.Copy(out, r); err != nil {
    log.Fatal(err)
}

关于python - Go中如何改进文件编码转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50860670/

相关文章:

python - 如何对二进制值数组的行进行排序,就好像它们是长二进制数一样?

python - Sublime Text 2 - 在解释器中运行选定的 python 代码

postgresql - 从 golang 查询 Postgres 复合类型

linux - 如何在 Bash 中检测文件是否具有 UTF-8 BOM?

python - 在python中将字节字符串转换为十六进制字符串

python - 添加输入变量以在 Python 中绘制标题/图例

python - 如何通过python在选定的Gmail邮箱中存档电子邮件

go - 直接调用函数和使用指针之间的不同行为

go - 如何在 Go 模板中访问数组第一个索引的值

c# - 如何确保我创建的文件下载是 UTF-8? (而不是没有 BOM 的 UTF-8)