有没有什么方法可以在不加载缓冲区中的所有内容的情况下读取和写入文件?
答案 0 :(得分: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
答案 1 :(得分:3)
您可以使用seek转到要阅读的文件部分。
来自文档:
要更改文件对象的位置,请使用f.seek(offset,from_what)。 通过向参考点添加偏移来计算位置;该 参考点由from_what参数选择。一个from_what 从文件开头的0度量值,1使用当前值 文件位置,2使用文件末尾作为参考点。 from_what可以省略,默认为0,使用的开头 file作为参考点。
在寻找之后,您可以读取字节或行,就像您最初正常加载的文件一样。
这是一个示例函数:
def special_read_file(filename, location, length):
file_handle = open(filename)
file_handle.seek(location, 0)
return file_handle.read(length)
位置和长度以字节为单位。 file_name将是您要读取的文件的locaiton的字符串。
你可以通过寻求做一些有趣而有趣的事情。使用它在文件中跳转,这样你就不必在本地存储文件内容,它仍然允许你遍历行。
正如其他一些答案已经提到的那样,使用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中创建自己的函数,而不是所有东西都需要内置。
答案 2 :(得分:1)
是的,你可以。例如,以下内容一次查看一行文件:
with open('data.txt') as f:
for line in f:
print line.strip()
这不会将整个文件加载到内存中。
答案 3 :(得分:1)
文件对象是可迭代的,所以你可以做你喜欢它们的事情。
例如,要从输入到输出写入每隔一行,请使用以下内容:
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)