我正在使用JHDF5将值的集合记录到hdf5文件中。我目前正在使用两个ArrayList来执行此操作,一个使用值,另一个使用值的名称。
ArrayList<String> valueList = new ArrayList<String>();
ArrayList<String> nameList = new ArrayList<String>();
valueList.add("Value1");
valueList.add("Value2");
nameList.add("Name1");
nameList.add("Name2");
IHDF5Writer writer = HDF5Factory.configure("My_Log").keepDataSetsIfTheyExist().writer();
HDF5CompoundType<List<?>> type = writer.compound().getInferredType("", nameList, valueList);
writer.compound().write("log1", type, valueList);
writer.close();
这会将值以正确的方式记录到文件My_Log和数据集“ log1”中。但是,此示例始终覆盖数据集“ log1”中值的先前日志。我希望每次都能登录到同一数据集,将最新的日志添加到数据集的下一行/索引。例如,如果我要将
"Name2"
的值更改为"Value3"
并记录值,然后将"Name1"
更改为"Value4"
,将"Name2"
更改为"Value5"
并记录值,则数据集应看起来像这样:我以为
keepDataSetsIfTheyExist()
选项可以防止数据集被覆盖,但是显然它不能那样工作。在某些情况下,使用
writer.compound().writeArrayBlock()
可以实现与我想要的类似的功能,并指定应将数组块写入哪个索引。但是,此解决方案似乎与我当前的代码不兼容,在此我必须使用列表来处理数据。是否有一些选择可以实现我所忽略的选项,或者使用JHDF5不能做到这一点吗?
最佳答案
我认为那行不通。对我来说还不太清楚,但是我相信您使用的getInferredType()正在创建一个具有2个name-> value条目的数据集。因此,它实际上是在hdf5内部创建一个对象。我能想到的最好的解决方案是读取之前的值,然后在输出之前将它们添加到valueList中:
ArrayList<String> valueList = new ArrayList<>();
valueList.add("Value1");
valueList.add("Value2");
try (IHDF5Reader reader = HDF5Factory.configure("My_Log.h5").reader()) {
String[] previous = reader.string().readArray("log1");
for (int i = 0; i < previous.length; i++) {
valueList.add(i, previous[i]);
}
} catch (HDF5FileNotFoundException ex) {
// Nothing to do here.
}
MDArray<String> values = new MDArray<>(String.class, new long[]{valueList.size()});
for (int i = 0; i < valueList.size(); i++) {
values.set(valueList.get(i), i);
}
try (IHDF5Writer writer = HDF5Factory.configure("My_Log.h5").writer()) {
writer.string().writeMDArray("log1", values);
}
如果第二次使用“ Value3”和“ Value4”调用此代码,则将获得4个值。但是,如果您开始具有数据集的层次结构,这种解决方案可能会变得不愉快。