在Python中将文件从latin1转换为utf-8的最快方法
我需要在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的建议澄清了一个条件。