在Python中将文件从latin1转换为utf-8的最快方法

6 投票
3 回答
9302 浏览
提问于 2025-04-15 20:10

我需要在Python中找到一种最快的方法,把文件从latin1格式转换成utf-8格式。这些文件很大,大约有2G。(我是在迁移数据库数据。)到目前为止,我有了

import codecs
infile = codecs.open(tmpfile, 'r', encoding='latin1')
outfile = codecs.open(tmpfile1, 'w', encoding='utf-8')
for line in infile:
     outfile.write(line)
infile.close()
outfile.close()

但这个方法还是很慢。转换的过程占用了整个迁移时间的四分之一。

如果有比Python代码更快的Linux命令行工具,我也可以使用它。

3 个回答

2

如果你非常想用Python(或者其他语言)来实现这个,至少在输入输出的时候要处理比一行更大的数据块,这样可以避免使用编解码器带来的额外开销。

infile = open(tmpfile, 'rb')
outfile = open(tmpfile1, 'wb')
BLOCKSIZE = 65536 # experiment with size
while True:
    block = infile.read(BLOCKSIZE)
    if not block: break
    outfile.write(block.decode('latin1').encode('utf8'))
infile.close()
outfile.close()

否则,建议使用iconv……我没有深入研究过它的内部实现,但如果它没有特别处理latin1格式的输入,我会感到很惊讶 :-)

6

我会选择使用 iconv 和一个系统调用。

4

你可以使用比一行更大的块来处理数据,这样做可能会让速度稍微快一点(不过在Linux上,二进制输入输出和文本输入输出是一样的,所以不会有速度提升):

 BLOCKSIZE = 1024*1024
 with open(tmpfile, 'rb') as inf:
   with open(tmpfile, 'wb') as ouf:
     while True:
       data = inf.read(BLOCKSIZE)
       if not data: break
       converted = data.decode('latin1').encode('utf-8')
       ouf.write(converted)

逐字节解析的方式,比如按行读取、行尾转换(在Linux上没有这个问题;-),以及用codecs.open风格的编码解码,可能是导致你速度慢的原因之一。这种方法也很通用(和你现在的方法一样),因为像\n这样的控制字符在这些编码之间根本不需要转换(在任何操作系统上都是如此)。

这种方法只适用于没有多字节字符的输入编码,但`latin1`就是其中之一(输出编码是否有这样的字符并不重要)。

尝试不同的块大小,找到性能最佳的那个,具体取决于你的硬盘、文件系统和可用的内存。

编辑:根据@John的评论修改了代码,并根据@gnibbler的建议澄清了一个条件。

撰写回答