这是一个错误吗?它演示了当您使用libtiff从打开的tiff文件句柄中提取图像时会发生什么。它适用于python 2.x,不适用于python 3.2.3。
import os
# any file will work here, since it's not actually loading the tiff
# assuming it's big enough for the seek
filename = "/home/kostrom/git/wiredfool-pillow/Tests/images/multipage.tiff"
def test():
fp1 = open(filename, "rb")
buf1 = fp1.read(8)
fp1.seek(28)
fp1.read(2)
for x in range(16):
fp1.read(12)
fp1.read(4)
fd = os.dup(fp1.fileno())
os.lseek(fd, 28, os.SEEK_SET)
os.close(fd)
# this magically fixes it: fp1.tell()
fp1.seek(284)
expect_284 = fp1.tell()
print ("expected 284, actual %d" % expect_284)
test()
我认为错误的输出是:预期为284,实际-504
取消对fp1.tell()的注释会产生一些...副作用...从而稳定了py3句柄,我不知道为什么。如果有人可以测试其他版本的python3,我也将不胜感激。
os.dup
创建一个引用相同打开文件描述的重复文件描述符。因此,os.lseek(fd, 28, SEEK_SET)
会更改fp1
底层文件的查找位置。
Python的文件对象缓存文件位置,以避免重复的系统调用。这样做的副作用是,在不使用文件对象方法的情况下更改文件位置将使缓存的位置与实际位置不同步,从而导致像您观察到的胡说八道。
更糟糕的是,由于文件是由Python内部缓冲的,因此在文件方法之外查找实际上可能导致返回的文件数据不正确,从而导致损坏或其他令人讨厌的东西。
bufferedio.c
中的文档指出,bufferedio.c
可用于重新初始化缓存的值:
tell
不,这不是错误。 Python 3 * The absolute position of the raw stream is cached, if possible, in the
`abs_pos` member. It must be updated every time an operation is done
on the raw stream. If not sure, it can be reinitialized by calling
_buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
also does it). To read it, use RAW_TELL().
(通过io
library调用为您提供文件对象)为您提供了buffered