这可能很简单,但我一直无法在线找到解决方案......我正在尝试使用一系列存储为 netcdf 文件的数据集。我打开每个文件,读入一些关键点,然后转到下一个文件。我发现我经常遇到 mmap 错误/脚本随着读取更多文件而变慢。我相信这可能是因为 netcdf 文件没有被 .close() 命令正确关闭。
我一直在测试这个:
from scipy.io.netcdf import netcdf_file as ncfile
f=ncfile(netcdf_file,mode='r')
f.close()
Run Code Online (Sandbox Code Playgroud)
那么如果我尝试
>>>f
<scipy.io.netcdf.netcdf_file object at 0x24d29e10>
Run Code Online (Sandbox Code Playgroud)
和
>>>f.variables['temperature'][:]
array([ 1234.68034431, 1387.43136567, 1528.35794546, ..., 3393.91061952,
3378.2844357 , 3433.06715226])
Run Code Online (Sandbox Code Playgroud)
所以看起来文件仍然打开?close() 实际上是做什么的?我怎么知道它起作用了?有没有办法从python关闭/清除所有打开的文件?
软件:Python 2.7.6、scipy 0.13.2、netcdf 4.0.1
其代码为f.close:
Definition: f.close(self)
Source:
def close(self):
"""Closes the NetCDF file."""
if not self.fp.closed:
try:
self.flush()
finally:
self.fp.close()
Run Code Online (Sandbox Code Playgroud)
f.fp是文件对象。所以
In [451]: f.fp
Out[451]: <open file 'test.cdf', mode 'wb' at 0x939df40>
In [452]: f.close()
In [453]: f.fp
Out[453]: <closed file 'test.cdf', mode 'wb' at 0x939df40>
Run Code Online (Sandbox Code Playgroud)
但通过使用f,我发现我仍然可以创建维度和变量。但f.flush()返回错误。
它看起来不像mmap在数据写入期间使用,而只是在读取期间使用。
def _read_var_array(self):
....
if self.use_mmap:
mm = mmap(self.fp.fileno(), begin_+a_size, access=ACCESS_READ)
data = ndarray.__new__(ndarray, shape, dtype=dtype_,
buffer=mm, offset=begin_, order=0)
else:
pos = self.fp.tell()
self.fp.seek(begin_)
data = fromstring(self.fp.read(a_size), dtype=dtype_)
data.shape = shape
self.fp.seek(pos)
Run Code Online (Sandbox Code Playgroud)
我没有太多的经验mmap。看起来它mmap基于文件中的字节块设置了一个对象,并将其用作变量的数据缓冲区。我不知道如果关闭底层文件,该访问会发生什么。如果出现某种mmap错误,我不会感到惊讶。
如果使用打开文件mmap=False,则整个变量将被读入内存,并像常规numpy数组一样进行访问。
mmap : None or bool, optional
Whether to mmap `filename` when reading. Default is True
when `filename` is a file name, False when `filename` is a
file-like object
Run Code Online (Sandbox Code Playgroud)
我的猜测是,如果您打开一个文件而不指定mmap模式,从中读取一个变量,然后关闭该文件,那么稍后引用该变量及其数据是不安全的。任何需要加载更多数据的引用都可能导致mmap错误。
但是,如果您使用 打开文件mmap=False,即使在关闭文件后您也应该能够对变量进行切片。
我不明白mmapfor 一个文件或变量如何干扰对其他文件和变量的访问。但我必须阅读更多内容mmap才能确定这一点。
从netcdf文档中:
请注意,当使用 netcdf_file 打开 mmap=True(默认为只读)的文件时,它返回的数组直接引用磁盘上的数据。如果此类数组处于活动状态,则不应关闭该文件,并且在询问时也无法彻底关闭该文件。如果要在文件关闭后对其进行处理,您可能需要复制从映射的 Netcdf 文件获取的数据数组,请参阅下面的示例。