随机存取
文件操作中,read()和write()都属于顺序存取,只能按顺序从头到尾的进行读写。实际上我们可以只访问文件中我们感兴趣的部分。对此,我们可以使用seek()和tell()方法。两种方法的help()返回结果如下。
1 >>> f = open("demo.txt","w") 2 >>> f.write("0123456789") 3 10 4 >>> f.close()
1 >>> help(f.seek) 2 Help on built-in function seek: 3 4 seek(cookie, whence=0, /) method of _io.TextIOWrapper instance 5 Change stream position. 6 7 Change the stream position to the given byte offset. The offset is 8 interpreted relative to the position indicated by whence. Values 9 for whence are: 10 11 * 0 -- start of stream (the default); offset should be zero or positive 12 * 1 -- current stream position; offset may be negative 13 * 2 -- end of stream; offset is usually negative 14 15 Return the new absolute position.
1 >>> help(f.tell) 2 Help on built-in function tell: 3 4 tell() method of _io.TextIOWrapper instance 5 Return current stream position.
seek的第一个参数——cookie——用来指示相对位移,可正可负可零,受限于第二个参数。必需。
seek的第二个参数——whence——用来指示参照物,0(io.SEEK_SET)代表文件开头,1(io.SEEK_CUR)代表当前位置,2(io.SEEK_END)代表文件末尾。默认为0。
1 >>> f = open("demo.txt","r") 2 >>> f.seek(0) 3 0 4 >>> f.seek(-1) 5 Traceback (most recent call last): 6 File "<pyshell#135>", line 1, in <module> 7 f.seek(-1) 8 ValueError: negative seek position -1 9 >>> f.seek(1) 10 1
默认/whence=0情况,相对位移只能为零或正数。
1 >>> f = open("demo.txt","r") 2 >>> f.seek(0,1) 3 0 4 >>> f.seek(-1,1) 5 Traceback (most recent call last): 6 File "<pyshell#126>", line 1, in <module> 7 f.seek(-1,1) 8 io.UnsupportedOperation: can't do nonzero cur-relative seeks 9 >>> f.seek(1,1) 10 Traceback (most recent call last): 11 File "<pyshell#127>", line 1, in <module> 12 f.seek(1,1) 13 io.UnsupportedOperation: can't do nonzero cur-relative seeks
当前/whence=1情况,相对位移只能为零。这是令人感到奇怪的,原因会在后面讲。
1 >>> f = open("demo.txt","r") 2 >>> f.seek(0,2) 3 10 4 >>> f.seek(-1,2) 5 Traceback (most recent call last): 6 File "<pyshell#119>", line 1, in <module> 7 f.seek(-1,2) 8 io.UnsupportedOperation: can't do nonzero end-relative seeks 9 >>> f.seek(1,2) 10 Traceback (most recent call last): 11 File "<pyshell#120>", line 1, in <module> 12 f.seek(1,2) 13 io.UnsupportedOperation: can't do nonzero end-relative seeks
末尾/whence=2情况,相对位移只能为零。这同样令人感到奇怪,原因会在后面讲。
问题
比较help文档的内容和我们前面所得,我们知道whence=1或2时,表现与预期不相符。这是由于打开方式的问题。以“t”方式(文本模式)打开的文件是无法从当前位置或末尾位置开始计算位移的,只允许从开头位置开始计算位移。注意观察上面代码的异常信息。第一段代码中报ValueError异常,而后面的报io.UnsupportedOperation异常。显然异常不同,造成异常的原因也不同。
想要从当前或末尾位置开始计算位移,应当使用“b”方式(二进制模式)打开文件。
1 >>> f = open("demo.txt","rb") 2 >>> f.seek(0) 3 0 4 >>> f.seek(-1) 5 Traceback (most recent call last): 6 File "<pyshell#106>", line 1, in <module> 7 f.seek(-1) 8 OSError: [Errno 22] Invalid argument 9 >>> f.seek(3) 10 3 11 >>> f.seek(0,1) 12 3 13 >>> f.seek(-1,1) 14 2 15 >>> f.seek(1,1) 16 3 17 >>> f.seek(0,2) 18 10 19 >>> f.seek(-1,2) 20 9 21 >>> f.seek(1,2) 22 11