Python 文件中的行是否读取整个文件

Python 文件中的行是否读取整个文件,python,Python,下面的代码是为每个循环读取一行,还是在开始迭代之前先将整个文件读入内存 for line in f: print(line) 我的意图是从文件中读取一行。它一次只读取一行,而不是一次将整个内容读入内存。这就是为什么会这样。你不能肯定。您所知道的是,它将一次返回一行。报告说: 为了使for循环成为在文件行上循环的最有效方式(一种非常常见的操作),next()方法使用隐藏的预读缓冲区。使用预读缓冲区的结果是,将next()与其他文件方法(如readline())结合使用无法正常工作 我的理

下面的代码是为每个循环读取一行,还是在开始迭代之前先将整个文件读入内存

for line in f:
    print(line)

我的意图是从文件中读取一行。

它一次只读取一行,而不是一次将整个内容读入内存。这就是为什么会这样。

你不能肯定。您所知道的是,它将一次返回一行。报告说: 为了使for循环成为在文件行上循环的最有效方式(一种非常常见的操作),next()方法使用隐藏的预读缓冲区。使用预读缓冲区的结果是,将next()与其他文件方法(如readline())结合使用无法正常工作

我的理解是,预读缓冲区加载一个完整的块(大小待定),并在该缓冲区中查找行尾。但是对于一个小文件(很少ko),您可以确保只有一次物理读取。有一次,我用
next
在一个小文件(大约50行)上获得第一行后,尝试将
读取的
放在一个小文件上,并在文件末尾找到了文件指针

当然,对于一个非常大的文件,它将一次物理读取一个块,python内存将一次使用一行。因此,它将比
readlines()
保守得多。但毕竟,在通用系统(类Unix、Mac OS或Windows)上,文件的底层读取系统调用(*)没有行尾的概念,只能读取(最大)字节数。因此,在这些系统上,无论您使用何种语言,都无法从物理上阅读到最后一行。您只能使用加载内部缓冲区然后在该缓冲区中查找行尾的实用程序。这就是Python中
next()
方法对文件对象所做的

在您的评论之后,我理解您试图只获得第一行。您可以通过以下方式完成:

line = f.next()
但在那之后不要尝试使用任何
read
方法,因为正如我上面解释的,文件指针可能远远超出第一行的末尾


(*)从控制台或终端设备读取数据时,情况会有所不同。

您可以这样做,也可以这样做:

f = open(' a file');

s = f.readlines(): # Read all lines, no looping

这一点在本文中提到。还有一个
list(f)
,它使您可以将行作为列表中的项目列出

如果您只需要读取一行,然后是二进制数据,您仍然需要以二进制模式打开文件。然后很容易模拟Python在读取行时所做的工作:读入临时缓冲区并搜索换行符。我假设文本采用8位ASCII兼容编码。您需要为
max\u line\u size
选择一些合理的最大行长度,否则算法会变得复杂得多

with open(filename, 'rb') as f:
    buffer = f.read(max_line_size)
    len = buffer.find(b'\n')
    if len < 0:
        raise RuntimeError('Line in file too long')
    line = buffer[:len]
    line = line.decode()
    f.seek(len + 1)
打开(文件名“rb”)作为f的
:
缓冲区=f.read(最大行大小)
len=buffer.find(b'\n')
如果len<0:
raise RUNTIMERROR('文件中的行太长')
行=缓冲区[:len]
line=line.decode()
f、 寻道(len+1)

你真的确定吗?我有一个文本文件,其中包含一些二进制数据。二进制数据的某个地方有一个字节(0x90),它抛出一个UnicodeDecodeError。它在for循环中失败,因此我不得不相信“for line in f”这一行是首先读取整个文件的,这样的循环不一定首先将整个文件加载到内存中。请参阅我添加到答案中的链接。至于一个文件一次实际加载到内存中的量,请参见@Serge的答案。对于非常小的文件,它可以查看整个文件和/或查看多行。这肯定会一次读取整个文件。我认为理想的结果是相反的。在这种情况下,我希望一次读取一行,而不是所有的行。@SSS那么您的初始解决方案是有效的,它会在读取文件中的每一行之前缓冲整个文件loop@SSS如果你只想一次读一行,为什么您关心Python在循环每一行之前是否读取整个文件?你能澄清一下你的局限性是什么,而不是一个一个地戳吗?@ha9u63ar这个解决方案有效,但不是我想象的那样。我希望它一次只读一行,但它似乎在读所有的行。你到底在找什么?这是你的好奇还是你脑子里有一个预期的操作?所以基本上我要做的是读取一个文件,当我遇到二进制数据时,它前面有一个指定二进制数据字节数的头,我想使用f.seek调用跳过这些二进制数据,但现在我明白我不能这样做,因为我不知道我的文件指针在哪里。@SSS:不幸的是,Python没有与C
fread
等效的,允许二进制读取与获取行的
fgets
同步。您必须使用
read
手动读取文件,并在缓存中查找行尾,以实现此功能。