用于file.read()的多字节请求的Python EOF

daw*_*awg 10 python eof

file.read()上的Python文档说明An empty string is returned when EOF is encountered immediately.文档进一步指出:

请注意,此方法可能会多次调用基础C函数fread(),以尽可能接近大小字节.另请注意,在非阻塞模式下,即使未给出大小参数,也可能返回的数据少于请求的数据.

我相信Guido已经提出了不添加f.eof()PERFECTLY CLEAR的观点,所以需要使用Python方式!

然而,我不清楚的是,如果你是一个确定的测试,如果你从读取中得到的字节数少于所要求的字节,那么你已经达到了EOF,但你确实得到了一些.

即:

with open(filename,'rb') as f:
    while True:
        s=f.read(size)
        l=len(s) 
        if l==0: 
            break     # it is clear that this is EOF...
        if l<size:
            break      # ? Is receiving less than the request EOF???
Run Code Online (Sandbox Code Playgroud)

break如果您收到的呼叫数少于呼叫中请求的字节数,那么这是一个潜在的错误file.read(size)吗?

the*_*olf 22

你不是在想你的蛇皮...... Python不是C.

首先,审查:

  • st = f.read()读取到EOF,或者如果以二进制形式打开,则读取到最后一个字节;
  • st = f.read(n)尝试读取n字节,在任何情况下都不会超过n字节;
  • st = f.readline()一次读一行,行以'\n'或EOF结尾;
  • st = f.readlines()使用readline()读取文件中的所有行并返回行列表.

如果文件读取方法是EOF,则返回''.相同类型的EOF测试用于其他'文件类似'的方法,如StringIO,socket.makefile等.从小于n字节的返回f.read(n)肯定不是EOF的决定性测试!虽然该代码可能工作99.99%时间,它是不起作用的时间,这将是非常令人沮丧的发现.另外,它是糟糕的Python形式.n在这种情况下唯一的用途是对返回的大小设置上限.

什么是一些Python的类似文件的方法返回的原因n字节?

  1. EOF当然是一个常见的原因;
  2. 网络套接字可能在读取时超时但仍保持打开状态;
  3. 完全n字节可能会导致逻辑多字节字符(例如\r\n在文本模式下,我认为是Unicode中的多字节字符)或某些您不知道的基础数据结构之间中断;
  4. 该文件处于非阻塞模式,另一个进程开始访问该文件;
  5. 临时不访问该文件;
  6. 文件,光盘,网络等的潜在错误情况,可能是暂时的.
  7. 程序收到一个信号,但信号处理程序忽略了它.

我会以这种方式重写你的代码:

with open(filename,'rb') as f:
    while True:
        s=f.read(max_size)
        if not s: break

        # process the data in s...
Run Code Online (Sandbox Code Playgroud)

或者,写一个生成器:

def blocks(infile, bufsize=1024):
    while True:
        try:
            data=infile.read(bufsize)
            if data:
                yield data
            else:
                break
        except IOError as (errno, strerror):
            print "I/O error({0}): {1}".format(errno, strerror)
            break

f=open('somefile','rb')

for block in blocks(f,2**16):
    # process a block that COULD be up to 65,536 bytes long
Run Code Online (Sandbox Code Playgroud)