Python行文件迭代与奇怪字符

2024-03-29 10:22:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个巨大的gzip文本文件需要逐行阅读。我同意以下几点:

for i, line in enumerate(codecs.getreader('utf-8')(gzip.open('file.gz'))):
  print i, line

在文件后期的某个时刻,python输出与文件不同。这是因为python认为是新行的奇怪的特殊字符导致了行被破坏。当我在“vim”中打开文件时,它们是正确的,但是可疑字符的格式却很奇怪。我能做些什么来解决这个问题吗?在

我试过其他编解码器,包括utf-16,拉丁语-1。我也试过没有编解码器。在

我用“od”查看了文件。果然,有些字符\n不应该出现。但是,那些“错误”的是一个奇怪的角色。我想这里有一些编码,有些字符是2字节,但是如果没有正确查看,后面的字节是\n a。在

根据'od-h file',违规字符是'1d1c'。在

如果我替换:

^{pr2}$

有:

os.popen('zcat file.gz')

它工作得很好(实际上,相当快)。但是,我想知道我错在哪里。在


Tags: 文件infor字节编解码器line字符utf
2条回答

我问(在一个评论中)“给我们看看print repr(奇怪的特殊字符)的输出。在vim中打开文件时,什么是正确的?请比“格式怪异”更精确。“但是没有:-(

你用od查看什么文件?file.gz??如果您可以在其中看到任何可识别的内容,那么它不是gzip文件!你看到的不是换行符,而是包含0x0A的二进制字节

如果原始文件是utf-8编码的,那么用其他编解码器尝试它有什么意义呢?在

“与zcat一起工作正常”是否意味着您可以在没有utf8解码步骤的情况下获得可识别的数据??在

我建议你简化你的代码,一步一步地来做。。。例如,请参见对this question的接受答案。再试一次,请显示您运行的确切代码,并在描述结果时使用repr()。在

更新看来DS已经猜到了您试图解释的\x1c和\x1d

下面是一些关于为什么会发生这种情况的注释:

在ASCII中,只有\r和\n在换行时才被考虑:

>>> import pprint
>>> text = ''.join('A' + chr(i) for i in range(32)) + 'BBB'
>>> print repr(text)
'A\x00A\x01A\x02A\x03A\x04A\x05A\x06A\x07A\x08A\tA\nA\x0bA\x0cA\rA\x0eA\x0fA\x10
A\x11A\x12A\x13A\x14A\x15A\x16A\x17A\x18A\x19A\x1aA\x1bA\x1cA\x1dA\x1eA\x1fBBB'
>>> pprint.pprint(text.splitlines(True))
['A\x00A\x01A\x02A\x03A\x04A\x05A\x06A\x07A\x08A\tA\n', # line break
 'A\x0bA\x0cA\r', # line break
 'A\x0eA\x0fA\x10A\x11A\x12A\x13A\x14A\x15A\x16A\x17A\x18A\x19A\x1aA\x1bA\x1cA\x
1dA\x1eA\x1fBBB']
>>>

但是在Unicode中,字符\x1D(文件分隔符)、\x1E(组分隔符)和\x1E(记录分隔符)也可以作为行尾:

^{pr2}$

不管你用什么编解码器都会发生这种情况。你仍然需要弄清楚你需要使用什么(如果有的话)编解码器。您还需要确定原始文件是否真的是文本文件而不是二进制文件。如果是文本文件,则需要考虑文件中\x1c和\x1d的含义。在

请在没有编解码器的情况下重试。以下内容再现了使用编解码器时的问题,以及没有编解码器时没有问题的情况:

import gzip 
import os 
import codecs 

data = gzip.open("file.gz", "wb") 
data.write('foo\x1d\x1cbar\nbaz') 
data.close() 

print list(codecs.getreader('utf-8')(gzip.open('file.gz'))) 
print list(os.popen('zcat file.gz')) 
print list(gzip.open('file.gz')) 

输出:

^{pr2}$

相关问题 更多 >