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

时间:2010-12-13 07:23:45

标签: python eof

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

  

请注意,此方法可能会调用   底层C函数fread()更多   一次努力获得as   尽可能接近大小字节。也   请注意,在非阻塞模式下,   数据少于要求的数据   返回,即使没有大小参数   得到了。

我相信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???

如果收到的break调用中请求的字节数少于{1}},那么file.read(size)可能会出现错误吗?

2 个答案:

答案 0 :(得分: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文件的方法返回 less 而不是n个字节的原因是什么?

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

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

    或者,写一个generator

    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
    

答案 1 :(得分:1)

以下是我的C编译器文档对fread()函数所说的内容:

size_t fread( 
   void *buffer,
   size_t size,
   size_t count,
   FILE *stream 
);
  

fread 会返回完整商品的数量   实际读,可能小于   计算是否发生错误或结束   之前遇到的文件   达到计数。

所以看起来小于size意味着发生了错误或者已经达到了EOF - 所以break离开循环是正确的事情。