read/write数据from/to大文件哪种方式更好?

Which way is better to read/write data from/to large files?

如果我们需要read/write一些数据from/to一个大文件每次before/after处理,下面哪种方式(有一些演示Python代码)是更好?

  1. 每次需要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 函数 loadsave 中采用了这种方式。我们直接调用 loadsave 而无需显式 openclose.

  2. 打开文件并关闭,直到我们完成所有工作,速度更快,但如果程序出现错误或文件被损坏[=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