我收到了几个文本文件,其中每个文件包含数千行文本。由于文件使用Unicode编码,因此每个文件最终大约为1GB。我知道这可能听起来很荒谬,但不幸的是现实:
我在Windows 7机器上使用Python 2.7。我只是开始使用Python,但认为这是一个真正开始使用该语言的好机会。你必须用它来学习它,对吗?
我希望能够复制所有这些大量文件。新副本将使用ASCII字符编码,理想情况下,其大小要小得多。我知道更改字符编码是一种解决方案,因为我通过在MS WordPad中打开文件并将其保存到常规文本文件取得了成功:
使用写字板是一个手动且缓慢的过程:我需要打开文件,这需要永远,因为它是如此之大,然后将其保存为新文件,这也需要永远,因为它是如此之大。我真的很想通过在后台运行脚本来自动执行此操作,同时处理其他事情。我写了一些Python来做这件事,但它没有正常工作。到目前为止我所做的是以下内容:
def convertToAscii():
# Getting a list of the current files in the directory
cwd = os.getcwd()
current_files = os.listdir(cwd)
# I don't want to mess with all of the files, so I'll just pick the second one since the first file is the script itself
test_file = current_files[1]
# Determining a new name for the ASCII-encoded file
file_name_length = len(test_file)
ascii_file_name = test_file[:file_name_length - 3 - 1] + "_ASCII" + test_file[file_name_length - 3 - 1:]
# Then we open the new blank file
the_file = open(ascii_file_name, 'w')
# Finally, we open our original file for testing...
with io.open(test_file, encoding='utf8') as f:
# ...read it line by line
for line in f:
# ...encode each line into ASCII
line.encode("ascii")
# ...and then write the ASCII line to the new file
the_file.write(line)
# Finally, we close the new file
the_file.close()
convertToAscii()
我最终得到以下错误:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte
但这没有任何意义....所有文本文件中的第一行是空行或一系列等号,例如===========。
我想知道是否有人能够让我走上正确的道路。据我所知,执行此操作可能需要很长时间,因为我实际上是逐行读取每个文件,然后将字符串编码为ASCII。为了解决当前的问题,我该怎么做?有没有更有效的方法来做到这一点?
答案 0 :(得分:4)
对于以ASCII格式存在的字符,UTF-8已使用单个字节进行编码。打开只包含单字节字符的UTF8文件,然后保存ASCII文件应该是非操作。
对于任何大小差异,您的文件必须是更宽泛的Unicode编码,如UTF-16 / UCS-2。这也解释了utf8编解码器抱怨源文件中的意外字节。
找出文件的实际编码,然后使用utf8编解码器保存。这样你的文件就像单字节字符一样小(相当于ASCII),但是如果你的源文件恰好有任何多字节字符,结果文件仍然可以对它们进行编码,你就不会做有损失的转换。
答案 1 :(得分:1)
如果你避免将文件拆分成行,那么可能会有一个加速,因为你唯一要做的就是将这些行重新组合在一起。这允许您以更大的块处理输入。
使用shutil.copyfileobj
函数(循环中只有read
和write
):
import shutil
with open('input.txt', encoding='u16') as infile, \
open('output.txt', 'w', encoding='u8') as outfile:
shutil.copyfileobj(infile, outfile)
(在这里使用Python 3,将encoding
参数直接传递给open
,但它应该与库函数io.open
相同。)