这是python 3文件错误吗? [英] Is this a python 3 file bug?

查看:63
本文介绍了这是python 3文件错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个错误吗?它演示了当您使用libtiff从打开的tiff文件句柄中提取图像时会发生什么.它适用于python 2.x,不适用于python 3.2.3

Is this a bug? It demonstrates what happens when you use libtiff to extract an image from an open tiff file handle. It works in python 2.x and does not work in 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

The output which I feel is in error is: expected 284, actual -504

取消对fp1.tell()的注释会产生一些...副作用...从而使py3句柄稳定下来,我不知道为什么.如果有人可以测试其他版本的python3,我也将不胜感激.

Uncommenting the fp1.tell() does some ... side effect ... which stabilizes the py3 handle, and I don't know why. I'd also appreciate if someone can test other versions of python3.

推荐答案

os.dup创建一个引用相同打开文件描述的重复文件描述符.因此,os.lseek(fd, 28, SEEK_SET)更改了fp1基础文件的查找位置.

os.dup creates a duplicate file descriptor that refers to the same open file description. Therefore, os.lseek(fd, 28, SEEK_SET) changes the seek position of the file underlying fp1.

Python的文件对象缓存文件位置,以避免重复的系统调用.这样做的副作用是,在不使用文件对象方法的情况下更改文件位置将使缓存的位置与实际位置不同步,从而导致像您观察到的胡说八道.

Python's file objects cache the file position to avoid repeated system calls. The side effect of this is that changing the file position without using the file object methods will desynchronize the cached position and the real position, leading to nonsense like you've observed.

更糟糕的是,由于文件是由Python内部缓冲的,因此在文件方法之外查找实际上可能导致返回的文件数据不正确,从而导致损坏或其他令人讨厌的东西.

Worse yet, because the files are internally buffered by Python, seeking outside the file methods could actually cause the returned file data to be incorrect, leading to corruption or other nasty stuff.

bufferedio.c 中的文档注意tell可用于重新初始化缓存的值:

The documentation in bufferedio.c notes that tell can be used to reinitialize the cached value:

* 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().

这篇关于这是python 3文件错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆