read/write数据from/to大文件哪种方式更好?
Which way is better to read/write data from/to large files?
如果我们需要read/write一些数据from/to一个大文件每次before/after处理,下面哪种方式(有一些演示Python代码)是更好?
每次需要read/writing时打开文件,reading/writing后立即关闭。这种方式似乎更安全?但是因为我们需要打开和关闭很多次所以速度较慢?
for i in processing_loop:
with open(datafile) as f:
read_data(...)
process_data(...)
with open(resultfile,'a') as f:
save_data(...)
这看起来很尴尬,但似乎 matlab 在其 .mat
文件 IO 函数 load
和 save
中采用了这种方式。我们直接调用 load
和 save
而无需显式 open
或 close
.
打开文件并关闭,直到我们完成所有工作,速度更快,但如果程序出现错误或文件被损坏[=54,文件可能会保持打开状态=] 如果程序意外终止。
fr = open(datafile)
fw = open(resultfile,'a')
for i in processing_loop:
read_data(...)
process_data(...)
save_data(...)
fr.close()
fw.close()
事实上,当程序被杀死时,我有几个 hdf5
文件以这种方式损坏。
似乎人们更喜欢第二种,将循环包装在 with
。
with open(...) as f:
...
或在异常捕获块中。
我知道这两个东西,我确实用过它们。但是当程序被杀死时,我的 hdf5
文件仍然损坏。
有一次我试图将一个巨大的数组写入hdf5文件,程序卡住了很长时间,所以我杀了它,然后文件就损坏了。
多次因为服务器突然宕机或者运行时间超过wall time导致程序终止
我没有注意是否只有在向文件写入数据时程序终止时才发生损坏。如果是这样,则意味着文件结构已损坏,因为它不完整。所以我想知道每次刷新数据是否有帮助,这会增加 IO 负载,但会减少终止时将数据写入文件的机会。
我尝试了第一种方式,仅在需要 reading/writing 数据时才访问文件。但显然速度慢了下来。当我们 open/close 一个文件句柄时,后台会发生什么?不只是 make/destroy 一个指针?为什么 open/close
操作成本如此之高?
您应该将解决方案 2 中的代码包装在 try except finally
中,并始终在 finally 中关闭文件。这样即使出现错误,您的文件也会自行关闭。
编辑:正如其他人指出的那样,您可以使用 with
来为您处理。
如果您担心在 "with" 语句中使用多个文件,您可以使用复合语句打开多个文件,或嵌套 "with" 块。这在此处的答案中有详细说明:
How to open a file using the open with statement
至于当程序出现错误时会发生什么,那是 try/except 块的目的。如果您知道预期会发生什么错误,则可以轻松包围 process_data() 调用。同样,一个 except 块可以捕获多个异常。
https://docs.python.org/3/tutorial/errors.html#handling-exceptions
如果我们需要read/write一些数据from/to一个大文件每次before/after处理,下面哪种方式(有一些演示Python代码)是更好?
每次需要read/writing时打开文件,reading/writing后立即关闭。这种方式似乎更安全?但是因为我们需要打开和关闭很多次所以速度较慢?
for i in processing_loop: with open(datafile) as f: read_data(...) process_data(...) with open(resultfile,'a') as f: save_data(...)
这看起来很尴尬,但似乎 matlab 在其.mat
文件 IO 函数load
和save
中采用了这种方式。我们直接调用load
和save
而无需显式open
或close
.打开文件并关闭,直到我们完成所有工作,速度更快,但如果程序出现错误或文件被损坏[=54,文件可能会保持打开状态=] 如果程序意外终止。
fr = open(datafile) fw = open(resultfile,'a') for i in processing_loop: read_data(...) process_data(...) save_data(...) fr.close() fw.close()
事实上,当程序被杀死时,我有几个hdf5
文件以这种方式损坏。
似乎人们更喜欢第二种,将循环包装在 with
。
with open(...) as f:
...
或在异常捕获块中。
我知道这两个东西,我确实用过它们。但是当程序被杀死时,我的 hdf5
文件仍然损坏。
有一次我试图将一个巨大的数组写入hdf5文件,程序卡住了很长时间,所以我杀了它,然后文件就损坏了。
多次因为服务器突然宕机或者运行时间超过wall time导致程序终止
我没有注意是否只有在向文件写入数据时程序终止时才发生损坏。如果是这样,则意味着文件结构已损坏,因为它不完整。所以我想知道每次刷新数据是否有帮助,这会增加 IO 负载,但会减少终止时将数据写入文件的机会。
我尝试了第一种方式,仅在需要 reading/writing 数据时才访问文件。但显然速度慢了下来。当我们 open/close 一个文件句柄时,后台会发生什么?不只是 make/destroy 一个指针?为什么 open/close
操作成本如此之高?
您应该将解决方案 2 中的代码包装在 try except finally
中,并始终在 finally 中关闭文件。这样即使出现错误,您的文件也会自行关闭。
编辑:正如其他人指出的那样,您可以使用 with
来为您处理。
如果您担心在 "with" 语句中使用多个文件,您可以使用复合语句打开多个文件,或嵌套 "with" 块。这在此处的答案中有详细说明:
How to open a file using the open with statement
至于当程序出现错误时会发生什么,那是 try/except 块的目的。如果您知道预期会发生什么错误,则可以轻松包围 process_data() 调用。同样,一个 except 块可以捕获多个异常。
https://docs.python.org/3/tutorial/errors.html#handling-exceptions