我有一个二进制文件,
file = open(fname,"Ub")
len(file.read())
在Python 3.3中,它返回1279200,这是正确的。在Python 2.7中,它返回1279106。
这是怎么回事?可能的原因是什么?
在2.7中,如何获得1279200字节?
答案 0 :(得分:1)
长话短说,U
和b
不会在一起。
Python 3遵循PEP-3116进行I / O实现。如果您查看open() implementation,您会注意到b
使用Buffered*
接口,而通用换行符则在TextIOWrapper中实现。因此,传递b
只会禁用支持通用换行符的代码。
实际上,如果您尝试同时启用二进制模式和通用换行符,则open()
的此实现甚至会失败。但是,此代码根本不支持U
模式参数,只支持显式newline
参数。
现在,我不知道为什么实际实现中的U
不会触发错误。也许这只是一个遗漏,也许它是为了向后兼容。
现在,Python 2有两个I / O实现。如果您使用io.open()
,则会获得与Python 3相同的行为。但是,您正在使用通过file type的C实现的遗留open()
(相关代码:{{3 },open(),field setting),此代码在二进制和文本文件支持之间没有明确的分离。因此,通用换行支持也适用于二进制文件。
因此,总结一下:您正在尝试使用两种冲突的文件模式。在Python 3中,这可能会触发错误,但不是出于某种原因。相反,b
强于U
而后者不起作用。在Python 2中,代码在二进制文件和文本文件之间没有明确的分割,b
和U
都受到尊重,具体取决于上下文。
快速测试:
$ printf '1\n2\r\n3\n\r4\r5' > f
$ ipython3.3
In [1]: open('f', 'Ub').read()
Out[1]: b'1\n2\r\n3\n\r4\r5'
$ ipython2.7
In [1]: import io
In [2]: io.open('f', 'Ub').read()
Out[2]: '1\n2\r\n3\n\r4\r5'
In [3]: open('f', 'Ub').read()
Out[3]: '1\n2\n3\n\n4\n5'
答案 1 :(得分:0)
引用python文档:
提供“U”将文件作为文本文件打开,但行可以是 由以下任何一种终止:Unix的行尾约定 '\ n',Macintosh约定'\ r'或Windows约定'\ r \ n'。 所有这些外部表示都被Python视为'\ n' 程序。如果构建Python而没有通用换行符支持模式 'U'与普通文本模式相同。请注意文件对象 open也有一个名为newlines的属性,其值为 无(如果尚未看到换行符),'\ n','\ r','\ r \ n'或者a 包含所有新行类型的元组。
我建议您使用'rb'/'wb'模式,这有效!
答案 2 :(得分:0)
在Python 3中'U'
mode is ignored:
'U'模式已弃用,将在未来版本中引发异常 Python它在Python 3中没有效果。使用
newline
来控制 通用换行模式。
'b'
以二进制模式打开文件,因此len(file.read())
返回文件中的字节数(os.path.getsize(filename)
)。
在Python 2中'U'
和'b'
can be combined。 'b'
设置f_binary
flag(就我所见,对阅读没有影响)并传递给platform-specific fopen()
(对Unix没有影响)。 'U'
启用通用换行模式(\r
,\r\n
转换为\n
)。如果文件中有\r\n
,它可能会改变读取字节数。