HDF5与文件夹有何不同?

Mar*_*son 50 python persistence metadata hdf5

我正在开发一个处理向文件夹添加元数据的开源项目.提供的(Python)API允许您浏览和访问元数据,就像它只是另一个文件夹一样.因为它只是另一个文件夹.

\folder\.meta\folder\somedata.json
Run Code Online (Sandbox Code Playgroud)

然后我遇到了HDF5及其派生的Alembic.

阅读Python和HDF5一书中的HDF5我在寻找使用它的好处与使用文件夹中的文件相比,但我遇到的大部分内容都谈到了分层文件格式在添加数据方面的简单性的好处通过其API:

>>> import h5py
>>> f = h5py.File("weather.hdf5")
>>> f["/15/temperature"] = 21
Run Code Online (Sandbox Code Playgroud)

或者它能够根据请求(例如随机访问)只读取它的某些部分,以及并行执行单个HDF5文件(例如,用于多处理)

您可以挂载HDF5文件,https://github.com/zjttoefs/hdfuse5

它甚至拥有强大而简单的群组数据集的基础概念,来自wiki的内容如下:

  • 数据集,是同类型的多维数组
  • 组,可以容纳数据集和其他组的容器结构

数据集替换为文件文件夹,整个功能集听起来像文件夹中的文件已经完全能够做到.

对于我遇到的每一个好处,没有一个突出显示HDF5专属.

所以我的问题是,如果我要给你一个HDF5文件和一个文件夹,两个内容相同,哪种情况下HDF5更适合?

编辑:

得到了一些关于HDF5可移植性的回应.

这听起来很可爱,但我还没有给出一个例子,一个场景,其中一个HDF5可以用文件输出一个文件夹.当文件夹在任何计算机上可读时,为什么有人会考虑使用HDF5,任何文件系统,通过网络,支持"并行I/O",没有HDF5解释器的人可读.

我甚至可以说,带文件的文件夹比任何HDF5都便携得多.

编辑2:

Thucydides411刚刚举了一个可移植性问题的例子. /sf/answers/1995841991/

我认为我从这个帖子的答案中拿走的是HDF5非常适合当你需要文件和文件夹的组织结构时,就像上面的示例场景一样,有很多(数百万)小(~1个字节)数据结构; 喜欢个别数字或字符串.它通过提供一个"子文件系统"来支持文件系统所缺少的东西,这种文件系统有利于小型和多型,而不是少量和大型.

在计算机图形学中,我们使用它来存储几何模型和关于各个顶点的任意数据,这些数据似乎与它在科学界的使用非常吻合.

Thu*_*411 68

作为开发从使用文件夹到HDF5的科学项目的人,我想我可以了解一下HDF5的优点.

当我开始我的项目时,我在小型测试数据集上运行,并产生少量输出,范围为千字节.我从最简单的数据格式开始,表格编码为ASCII.对于我处理的每个对象,我在ASCII表上生成.

我开始将我的代码应用于对象组,这意味着在每次运行结束时编写多个ASCII表,以及包含与整个组相关的输出的附加ASCII表.对于每个组,我现在有一个文件夹,看起来像:

+ group
|    |-- object 1
|    |-- object 2
|    |-- ...
|    |-- object N
|    |-- summary
Run Code Online (Sandbox Code Playgroud)

在这一点上,我开始遇到我的第一个困难.ASCII文件的读写速度非常慢,并且它们不能非常有效地打包数字信息,因为每个数字需要一个完整的字节进行编码,而不是~3.3位.所以我切换到将每个对象写为自定义二进制文件,这加快了I/O并减小了文件大小.

随着我扩展到处理大量(数万到数百万)组,我突然发现自己处理了大量的文件和文件夹.拥有太多小文件可能是许多文件系统的问题(许多文件系统在它们可以存储的文件数量方面受到限制,无论有多少磁盘空间).我也开始发现,当我尝试对整个数据集进行后期处理时,读取许多小文件的磁盘I/O开始占用相当多的时间.我试图通过合并我的文件来解决这些问题,因此我只为每个组生成了两个文件:

+ group 1
|    |-- objects
|    |-- summary
+ group 2
|    |-- objects
|    |-- summary
...
Run Code Online (Sandbox Code Playgroud)

我还想压缩我的数据,所以我开始为组的集合创建.tar.gz文件.

此时,我的整个数据方案变得非常繁琐,如果我想将数据交给其他人,则可能需要花费很多精力向他们解释如何使用它.例如,包含对象的二进制文件具有自己的内部结构,该结构仅存在于存储库中的README文件中以及办公室中的纸垫上.想要读取我的组合对象二进制文件之一的人必须知道标头中每个元数据条目的字节偏移量,类型和字节顺序,以及文件中每个对象的字节偏移量.如果他们不这样做,该文件将是他们的胡言乱语.

我分组和压缩数据的方式也带来了问题.假设我想找一个对象.我必须找到它所在的.tar.gz文件,将存档的全部内容解压缩到一个临时文件夹,导航到我感兴趣的组,并使用我自己的自定义API检索该对象以读取我的二进制文件.完成后,我会删除临时解压缩的文件.这不是一个优雅的解决方案.

此时,我决定切换到标准格式.由于多种原因,HDF5具有吸引力.首先,我可以将数据的整体组织保持为组,对象数据集和摘要数据集.其次,我可以放弃我的自定义二进制文件I/O API,只需使用多维数组数据集来存储组中的所有对象.我甚至可以创建更复杂的数据类型的数组,比如C结构数组,而不必仔细记录每个条目的字节偏移量.接下来,HDF5具有分块压缩,这对于数据的最终用户来说是完全透明的.因为压缩是分块的,如果我认为用户想要查看单个对象,我可以将每个对象压缩在一个单独的块中,这样只需要解压缩用户感兴趣的数据集部分.分块压缩是一个非常强大的功能.

最后,我现在可以给一个人一个文件,而不必解释它是如何在内部组织的.最终用户可以使用Python,C,Fortran或h5ls命令行或GUI HDFView 读取文件,并查看其中的内容.我的自定义二进制格式无法实现这一点,更不用说我的.tar.gz集合了.

当然,可以使用文件夹,ASCII和自定义二进制文件复制HDF5可以执行的所有操作.这就是我最初做的事情,但它成了一个令人头痛的问题,最后,HDF5以高效便携的方式完成了我所做的一切.

  • 确实很有趣;+1 (3认同)

Ted*_*ann 10

感谢您提出这个有趣的问题.文件夹是否具有可移植文件,因为我可以将目录复制到Mac上的棒上,然后在PC上查看相同的目录和文件?我同意文件目录结构是可移植的,这要归功于编写操作系统的人,但这与可移植文件中的数据无关.现在,如果此目录中的文件是pdf,则它们是可移植的,因为有些工具可以在多个操作系统中读取和理解pdf(感谢Adobe).但是,如果这些文件是原始科学数据(ASCII或二进制无关紧要),它们根本不是可移植的.ASCII文件看起来像一堆字符,二进制文件看起来像乱码.如果是XML或json文件,它们是可读的,因为json是ASCII,但它们包含的信息可能不可移植,因为没有写入文件的人可能不清楚XML/json标记的含义.这一点非常重要,ASCII文件中的字符是可移植的,但它们所代表的信息却不是.

HDF5数据是可移植的,就像pdf一样,因为许多操作系统中都有工具可以读取HDF5文件中的数据(就像pdf阅读器一样,请参阅http://www.hdfgroup.org/products/hdf5_tools/index.html).还有许多语言的库可用于读取数据并以对用户有意义的方式呈现 - 这是Adobe读者所做的.HDF5社区中有数百个小组为其用户执行相同的操作(请参阅http://www.hdfgroup.org/HDF5/users5.html).

这里也有一些关于压缩的讨论.在HDF5文件中压缩的重要一点是,对象是独立压缩的,只有你需要的对象在输出时被解压缩.这显然比压缩整个文件更有效,并且必须解压缩整个文件才能读取它.

另一个关键部分是HDF5文件是自描述的 - 因此,编写文件的人可以添加信息,帮助用户和工具知道文件中的内容.什么是变量,它们的类型是什么,软件编写它们,收集它们的仪器等等.听起来你正在使用的工具可以读取文件的元数据.HDF5文件中的属性可以附加到文件中的任何对象 - 它们不仅仅是文件级信息.这是巨大的.当然,可以使用以多种语言和许多操作系统编写的工具来读取这些属性.


Sim*_*mon 2

我认为主要优点是便携性

HDF5 存储有关数据集的信息,例如整数和浮点数的大小、类型和字节顺序,这意味着您可以移动 hdf5 文件并读取其内容,即使它是在具有不同架构的计算机上创建的。

您还可以将任意元数据附加到组和数据集。可以说,如果您的文件系统支持扩展属性,您也可以对文件和文件夹执行此操作。

hdf5 文件是单个文件,有时比 zip/tar 文件夹和文件更方便。这样做还有一个主要缺点:如果删除数据集,则在不创建新文件的情况下无法回收空间。

一般来说,HDF5 非常适合存储大量数字,通常是科学数据集。

  • 假设您想在磁盘上存储一个 4 字节整数。你需要一个 4 字节的文件,对吗?现在,如果您要将这个 4 字节文件移动到另一台计算机并加载该数字,您最终可能会得到不同的数字。原因是字节的顺序可能不同。因此,事实上,为了使您的(二进制)文件具有可移植性,它需要更多的位来存储有关字节排序(元数据)的信息。HDF5 会为您做到这一点。 (4认同)
  • **纯文本**(JSON、XML…)非常可移植(除了编码问题),但**二进制**则不然。例如,如果您在计算机上使用“fwrite”(C语言)在文件中写入数字数组,将该文件移动到具有不同架构的另一台计算机并尝试使用“fread”读取它,它不会按预期工作。 (2认同)