有什么办法可以在不将所有内容加载到缓冲区的情况下读写文件?
4 回答
文件对象是可迭代的:
with open(filename) as f:
for line in f:
do_something(line)
迭代它们一次会产生 1 行(并且不会将整个文件存储在内存中)
编写文件同样简单:
with open(filename,'w') as f:
for x in get_data():
f.write(x)
或者您可以使用writelines
传入生成器的方法。例如f.writelines(get_data())
其中get_data
可以定义为:
def get_data():
for i in xrange(200):
yield '%d\n'%i
您可以使用seek for 转到要读取的文件部分。
来自文档:
要更改文件对象的位置,请使用 f.seek(offset, from_what)。位置是通过将偏移量添加到参考点来计算的;参考点由 from_what 参数选择。from_what 值为 0 从文件开头测量,1 使用当前文件位置,2 使用文件末尾作为参考点。from_what 可以省略,默认为 0,使用文件的开头作为参考点。
在寻找之后,您可以读取字节或行,就像您最初正常加载文件一样。
这是一个示例函数:
def special_read_file(filename, location, length):
file_handle = open(filename)
file_handle.seek(location, 0)
return file_handle.read(length)
位置和长度以字节为单位。file_name 将是您要读取的文件的位置字符串。
你可以用 seek 做一些有趣的事情。使用它在文件中跳转,这样您就不必在本地存储文件内容,它仍然可以让您遍历行。
with
正如其他一些答案已经提到的那样,使用和迭代文件行for line in file
是保持系统内容轻松的好方法。但是传递一个 file_handle 要简单得多,您不必一直打开和关闭或读取它的一部分,您可以打开一个句柄,然后在需要该特定文件时从您需要的位置读取。
在这里,我写了一个生成器函数,它可以像往常一样工作,只有你可以指定从文件的哪个部分开始读取。
def read_handle_from(file_handle, start_point):
file_handle.seek(start_point, 0)
for line in file_handle:
yield line
my_file_handle = open(file_name)
for line in read_handle_from(my_file_handle, 2000):
#do stuff
您可以轻松地修改函数以限制读取的行数,或根据需要读取的字节数。
它很容易为自己创建函数和生成器以使用你想要的方式,不要害怕在 python 中创建你自己的函数,并不是所有的东西都需要内置。
文件对象是可迭代的,因此您可以随心所欲地使用它们。
例如,要从输入到输出每隔一行写入一次,请使用以下内容:
from itertools import islice
with open('input') as fin, open('output', 'w') as fout:
every_other = islice(fin, None, None, 2)
fout.writelines(every_other)
是的你可以。例如,下面一行一行地查看一个文件:
with open('data.txt') as f:
for line in f:
print line.strip()
这不会将整个文件加载到内存中。