Python 2.7: len() 对包含换行符的文件行返回错误值
我在64位的Windows 7上使用WinPython 2.7。
我想打开一个文件,逐行读取内容,当遇到某个特定的序列时,我想从那里继续处理文件内容。
为了保存当前的位置,我把当前行的长度添加到一个行长度的列表里。但是,len(line)
返回的值比实际少了1。我怀疑这可能和Windows的换行符\r\n
有关。
下面是一个示例代码。
testfile.txt:
Line1 Line2 Line3
test.py
fn = 'testfile.txt' f = open(fn) line_offsets = [] for line in f: line_offsets.append(len(line)) f.seek(line_offsets[1]) print '%r' % f.read()
输出结果:
'\nLine2\nLine3'
预期输出:
'Line2\nLine3'
我尝试通过指定读取方法来打开文件(使用通用换行符):f = open(fn, 'rU')
,但这也没有解决问题。如果我以二进制模式打开文件是可以的,但这个实际上是一个文本文件,而不是二进制文件,所以我想避免这样做,同时我也想搞清楚这里发生了什么。
3 个回答
0
为了实现你想要的效果,你可以在读取每一行之前,先调用一下 f.tell()
,然后再用 f.readline()
来读取这一行。由于某些原因,你可能还需要以二进制模式打开文件,这和 Windows系统中tell()的一个问题有关,同时你也需要自己处理行结束符的问题。直接把文件当成一个迭代器来用是行不通的,因为这样会有缓存,可能会导致文件指针移动到你正在读取的行的后面。
>>> with open('testfile.txt', 'rb') as f:
... while True:
... here = f.tell()
... line = f.readline()
... if not line:
... break
... print('%02d\t%r' % (here, line))
...
00 'Line1\n'
06 'Line2\n'
12 'Line3\n'
0
你可以使用 splitlines()
这个方法来获取文件中的每一行。这个方法能够处理不同类型的换行符,具体的可以参考 文档。
4
以二进制模式打开文件,这样行中的 '\r'
就不会被去掉了。这样 len
就能正确返回字节数。
f = open(fn, 'rb')
如果你要迁移到 Python 3,这一点特别重要,因为非二进制文件在读取时会把字节解码成 Unicode 字符,这样计算的数量可能会大大不准确。