Python二进制EOF

Python二进制EOF,python,binary,eof,Python,Binary,Eof,我想读一个二进制文件。 谷歌搜索“python二进制eof”让我觉得 现在,问题是: 为什么容器(SO答案中的x)不包含单个(当前)字节,而是包含一大堆字节?我做错了什么 如果应该是这样,而我没有做错什么,那么如何读取单个字节?我的意思是,在使用read(1)方法读取文件时,是否有任何方法可以检测EOF 逐字节读取: with open(filename, 'rb') as f: while True: b = f.read(1) if not b:

我想读一个二进制文件。 谷歌搜索“python二进制eof”让我觉得

现在,问题是:

  • 为什么容器(SO答案中的x)不包含单个(当前)字节,而是包含一大堆字节?我做错了什么
  • 如果应该是这样,而我没有做错什么,那么如何读取单个字节?我的意思是,在使用
    read(1)
    方法读取文件时,是否有任何方法可以检测EOF
  • 逐字节读取:

    with open(filename, 'rb') as f:
        while True:
            b = f.read(1)
            if not b:
                # eof
                break
            do_something(b)
    
    将表示文件结束

    with open(filename, 'rb') as f:
        for ch in iter(lambda: f.read(1),""): # keep calling f.read(1) until end of the data
            print ch
    
    引述:

    文件。读取([size])

    从文件中最多读取大小字节(如果读取在获取大小字节之前达到EOF,则读取量将减少)。如果size参数为负数或省略,则读取所有数据,直到达到EOF。字节作为字符串对象返回立即遇到EOF时返回空字符串。(对于某些文件,如TTY,在点击EOF后继续读取是有意义的。)注意,此方法可能多次调用底层C函数fread(),以获取尽可能接近大小的字节。还请注意,在非阻塞模式下,即使未给出大小参数,返回的数据也可能少于请求的数据

    这意味着(对于a):

    • f.read(1)
      将返回一个字节对象,如果达到EOF,则该对象包含1字节或0字节
    • f.read(2)
      将返回包含2个字节的字节对象,如果在第一个字节之后达到EOF,则返回1个字节;如果立即遇到EOF,则返回0个字节
    如果要一次读取一个字节的文件,则必须在循环中读取(1),并测试结果是否为“空”:

    # From answer by @Daniel
    with open(filename, 'rb') as f:
        while True:
            b = f.read(1)
            if not b:
                # eof
                break
            do_something(b)
    
    如果您想一次按50字节的“块”读取文件,则必须在循环中
    读取(50)

    with open(filename, 'rb') as f:
        while True:
            b = f.read(50)
            if not b:
                # eof
                break
            do_something(b) # <- be prepared to handle a last chunk of length < 50
                            #    if the file length *is not* a multiple of 50
    
    再次引用:

    文件对象是它自己的迭代器[…]。当文件用作迭代器时,通常在for循环中(例如,对于f:print line.strip()中的行),会重复调用next()方法。此方法返回下一输入行,或在文件打开读取时点击EOF时引发StopIteration(文件打开写入时行为未定义)

    上面的代码逐行读取二进制文件。在每次出现下线字符(
    \n
    )时停止。通常,这会导致不同长度的块,因为大多数二进制文件都包含随机分布的字符


    我不鼓励您以这种方式读取二进制文件。请选择一个基于
    read(size)

    的解决方案以下是我所做的。调用
    read
    在遇到文件结尾时返回一个falsy值,这将终止循环。使用
    while ch!=“”:
    复制了图像,但它给了我一个挂起的循环

    from sys import argv
    donor = argv[1]
    recipient = argv[2]
    # read from donor and write into recipient
    # with statement ends, file gets closed
    with open(donor, "rb") as fp_in:
        with open(recipient, "wb") as fp_out:
            ch = fp_in.read(1)
            while ch:
                fp_out.write(ch)
                ch = fp_in.read(1)
    

    我不知道为什么我不能从社区得到一些无害的帮助?为什么那些不值得5页的答案、一个维基页面或伟大人物进入光荣名人堂的问题总是被否决?为什么我应该只问火箭科学?如果你不满意你的问题在这里被理解的方式,一个不恰当的反应的评论,因为向下的投票者早就走了——并且可能不会读到这个评论。但其他国家的人民会这样做。如果你真的不同意,并且绝对肯定你的问题会到达这里,你可以提出你的理由。但在这么做之前,有太多的答案都是不可行的!谢谢你发布了一个伟大而详细的答案!!!没有这个答案,我不可能完成我的项目!对于f.read(1)示例:如果您的字节流中有一个零字节,那么测试将在您完成读取之前提前退出file@slashdottir在Python中,只有空序列是False(),凡是不为False的都是True。因此,如果字节字符串包含\x00,则它不是空的,因此
    b“\x00”
    为真。您可以在REPL:
    “T”if b“\x00”else“F”
    单词中测试这一点。在这里,了解缓冲文件时引擎盖下发生的事情很重要。实际上,正在创建几个缓冲区对象,其中包含缓冲文件的一部分。看见Python应该使这一点变得不太可能,但由此产生的典型问题是,完成后,文件的一部分仍然位于底层缓冲区对象中。如果数据丢失,一定要刷新它们。我不喜欢break语句。它使while的谓词在退出时为false的保证无效。但如果文件包含零字节,则会在文件完全关闭之前提前结束read@slashdottir:错了<代码>不是“\0”是
    False
    。只有
    不是“”
    真的
    for x in file:  
       i=i+1  
       print(x)  
    
    from sys import argv
    donor = argv[1]
    recipient = argv[2]
    # read from donor and write into recipient
    # with statement ends, file gets closed
    with open(donor, "rb") as fp_in:
        with open(recipient, "wb") as fp_out:
            ch = fp_in.read(1)
            while ch:
                fp_out.write(ch)
                ch = fp_in.read(1)