dcb
2025-06-19 50155d2d6da56ac59a672755a704ed1503ffe3f6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
package com.se.nsl.helper;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
 
import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;
 
public class H5ReadHelper {
    //传入跟组
    private static String PATH = "/";
    //数据集名称
    private static String DATASETNAME;
    //设置数据集行数  之后会动态获得行数,实现对应缩容(建议初始值设置大些)
    private static final long DIM0 = 100000;
    //设置整型长度
    protected static final int INTEGERSIZE = 4;
    //设置长整型长度
    protected static final int LONGSIZE = 8;
    //设置单精度长度
    protected static final int FLOATSIZE = 4;
    //设置双精度型长度
    protected static final int DOUBLESIZE = 8;
    //设置字符串最大长度
    protected final static int MAXSTRINGSIZE = 80;
 
    static class Sensor_Datatype {
        static int numberMembers = 5;//表示列项数
        static int[] memberDims = {1, 1, 1, 1, 1};
        static String[] memberNames = {  //定义表中所有字段名称
                "trading_day", "updatetime", "instrument_id", "gap_number", "reserve"
        };//数据元素为具体的表字段名称
        static long[] memberMemTypes = {  //对应字段类型值
                HDF5Constants.H5T_NATIVE_INT, HDF5Constants.H5T_NATIVE_LONG, HDF5Constants.H5T_NATIVE_FLOAT, HDF5Constants.H5T_NATIVE_DOUBLE, HDF5Constants.H5T_C_S1
        };//用于定义每个字段元素的类型  指定字段元素类型的时候注意类型长度,如果小于存储数长度,则会发生数据溢出
        static long[] memberFileTypes = { //对应字段类型大小
                HDF5Constants.H5T_STD_I32BE, HDF5Constants.H5T_STD_I64BE, HDF5Constants.H5T_IEEE_F32BE, HDF5Constants.H5T_IEEE_F64BE, HDF5Constants.H5T_C_S1
        };//对应的字段类型的大小
        static int[] memberStorage = {  //对应字段类型值长度
                INTEGERSIZE, LONGSIZE, FLOATSIZE, DOUBLESIZE, MAXSTRINGSIZE
        };//定义对应类型的长度大小
 
        // Data size is the storage size for the members.
        static long getTotalDataSize() {
            long data_size = 0;
            for (int indx = 0; indx < numberMembers; indx++) {
                data_size += memberStorage[indx] * memberDims[indx];
            }
            return DIM0 * data_size;
        }
 
        static long getDataSize() {
            long data_size = 0;
            for (int indx = 0; indx < numberMembers; indx++) {
                data_size += memberStorage[indx] * memberDims[indx];
            }
            return data_size;
        }
 
        static int getOffset(int memberItem) {
            int data_offset = 0;
            for (int indx = 0; indx < memberItem; indx++) {
                data_offset += memberStorage[indx];
            }
            return data_offset;
        }
    }
 
    static class Sensor {
        public Integer trading_day;
        public Long updatetime;
        public Float instrument_id;
        public Double gap_number;
        public String reserve;
 
        public Sensor(Integer trading_day, Long updatetime, Float instrument_id, Double gap_number, String reserve) {
            super();
            this.trading_day = trading_day;
            this.updatetime = updatetime;
            this.instrument_id = instrument_id;
            this.gap_number = gap_number;
            this.reserve = reserve;
        }
 
        Sensor(ByteBuffer databuf, int dbposition) {
            readBuffer(databuf, dbposition);
        }
 
        //遍历.h5下边的所有数据集,并以数组的方式返回数据集名称
        private static String[] do_iterate(String filePath) {
            int file_id = -1;
 
            // Open a file using default properties.
            try {
                file_id = H5.H5Fopen(filePath, HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT);
            } catch (Exception e) {
                e.printStackTrace();
            }
 
            // Begin iteration.
            System.out.println("Objects in root group:");
            try {
                if (file_id >= 0) {
                    int count = (int) H5.H5Gn_members(file_id, PATH);
                    String[] oname = new String[count];
                    int[] otype = new int[count];
                    int[] ltype = new int[count];
                    long[] orefs = new long[count];
                    H5.H5Gget_obj_info_all(file_id, PATH, oname, otype, ltype, orefs, HDF5Constants.H5_INDEX_NAME);
                    // Get type of the object and display its name and type.
                    for (int indx = 0; indx < otype.length; indx++) {
                        switch (H5O_type.get(otype[indx])) {
                            case H5O_TYPE_GROUP:
                                System.out.print("  Group: " + oname[indx] + "," + oname.length + " ");
                                break;
                            case H5O_TYPE_DATASET:
                                System.out.print("  Dataset: " + oname[indx] + "," + oname.length + " ");
                                break;
                            case H5O_TYPE_NAMED_DATATYPE:
                                System.out.print("  Datatype: " + oname[indx] + "," + oname.length + " ");
                                break;
                            default:
                                System.out.print("  Unknown: " + oname[indx] + "," + oname.length + " ");
                        }
                    }
                    System.out.println();
                    return oname;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
 
            // Close the file.
            try {
                if (file_id >= 0) {
                    H5.H5Fclose(file_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new String[]{"数据集遍历出错"};
        }
 
        //读数据
        void readBuffer(ByteBuffer databuf, int dbposition) {
            //0
            this.trading_day = databuf.getInt(dbposition + Sensor_Datatype.getOffset(0));
            //1
            this.updatetime = databuf.getLong(dbposition + Sensor_Datatype.getOffset(1));
            //2
            this.instrument_id = databuf.getFloat(dbposition + Sensor_Datatype.getOffset(2));
            //3
            this.gap_number = databuf.getDouble(dbposition + Sensor_Datatype.getOffset(3));
            //4
            ByteBuffer stringbuf_reserve = databuf.duplicate();
            stringbuf_reserve.position(dbposition + Sensor_Datatype.getOffset(4));
            stringbuf_reserve.limit(dbposition + Sensor_Datatype.getOffset(4) + MAXSTRINGSIZE);
            byte[] bytearr_reserve = new byte[stringbuf_reserve.remaining()];
            stringbuf_reserve.get(bytearr_reserve);
            this.reserve = new String(bytearr_reserve, Charset.forName("UTF-8")).trim();
        }
 
        //重写toString()方法
        @Override
        public String toString() {
            DecimalFormat df = new DecimalFormat("#0.0000");//浮点数保留4位小数,不足,用0补齐
            return trading_day + ", " + updatetime + ", "
                    + df.format(instrument_id) + ", " + df.format(gap_number) + ", " + reserve;
        }
    }
 
    //读取表结构数据集
    private static void ReadDataset(String filePath) {
        int file_id = -1;
        int strtype_id = -1;
        int memtype_id = -1;
        int dataspace_id = -1;
        int dataset_id = -1;
        long[] dims = {DIM0};
        Sensor[] object_data2 = new Sensor[(int) dims[0]];
        ;
        byte[] dset_data;
        String[] dsetName = {};
        //遍历.h5文件下边的所有数据集
        dsetName = Sensor.do_iterate(filePath);
        //遍历得到文件下边的各个数据集  Open an existing dataset.
        for (int i = 0; i < dsetName.length; i++) {
            try {
                file_id = H5.H5Fopen(filePath, HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT);
            } catch (Exception e) {
                e.printStackTrace();
            }
            DATASETNAME = dsetName[i];
            try {
                if (file_id >= 0) {
                    dataset_id = H5.H5Dopen(file_id, DATASETNAME, HDF5Constants.H5P_DEFAULT);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Get dataspace and allocate memory for read buffer.
            try {
                if (dataset_id >= 0) {
                    dataspace_id = H5.H5Dget_space(dataset_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (dataspace_id >= 0) {
                    H5.H5Sget_simple_extent_dims(dataspace_id, dims, null);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Create string datatype.
            try {
                strtype_id = H5.H5Tcopy(HDF5Constants.H5T_C_S1);
                if (strtype_id >= 0) {
                    H5.H5Tset_size(strtype_id, MAXSTRINGSIZE);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Create the compound datatype for memory.
            try {
                memtype_id = H5.H5Tcreate(HDF5Constants.H5T_COMPOUND, Sensor_Datatype.getDataSize());
                if (memtype_id >= 0) {
                    for (int indx = 0; indx < Sensor_Datatype.numberMembers; indx++) {
                        int type_id = (int) Sensor_Datatype.memberMemTypes[indx];
                        if (type_id == HDF5Constants.H5T_C_S1) {
                            type_id = strtype_id;
                        }
                        H5.H5Tinsert(memtype_id, Sensor_Datatype.memberNames[indx], Sensor_Datatype.getOffset(indx),
                                type_id);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // allocate memory for read buffer.
            dset_data = new byte[(int) dims[0] * (int) Sensor_Datatype.getDataSize()];
            // Read data.
            try {
                if ((dataset_id >= 0) && (memtype_id >= 0)) {
                    H5.H5Dread(dataset_id, memtype_id, HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
                            HDF5Constants.H5P_DEFAULT, dset_data);
                }
                ByteBuffer inBuf = ByteBuffer.wrap(dset_data);
                inBuf.order(ByteOrder.nativeOrder());
                for (int indx = 0; indx < (int) dims[0]; indx++) {
                    object_data2[indx] = new Sensor(inBuf, indx * (int) Sensor_Datatype.getDataSize());//将读取到的数据存入该数组
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Output the data to the screen.
            for (int indx = 0; indx < dims[0]; indx++) {
                System.out.println(DATASETNAME + " [" + indx + "]:");
                System.out.println(object_data2[indx].toString());
            }
            //写到本地的文本中
            H5ReadHelper.writeLocalExcel(object_data2, DATASETNAME, dims[0]);
            try {
                if (dataset_id >= 0) {
                    H5.H5Dclose(dataset_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Terminate access to the data space.
            try {
                if (dataspace_id >= 0) {
                    H5.H5Sclose(dataspace_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Terminate access to the mem type.
            try {
                if (memtype_id >= 0) {
                    H5.H5Tclose(memtype_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (strtype_id >= 0) {
                    H5.H5Tclose(strtype_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // Close the file.
            try {
                if (file_id >= 0) {
                    H5.H5Fclose(file_id);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
    }
 
    enum H5O_type {
        H5O_TYPE_UNKNOWN(-1), // Unknown object type
        H5O_TYPE_GROUP(0), // Object is a group
        H5O_TYPE_DATASET(1), // Object is a dataset
        H5O_TYPE_NAMED_DATATYPE(2), // Object is a named data type
        H5O_TYPE_NTYPES(3); // Number of different object types
        private static final Map<Integer, H5O_type> lookup = new HashMap<Integer, H5O_type>();
 
        static {
            for (H5O_type s : EnumSet.allOf(H5O_type.class)) {
                lookup.put(s.getCode(), s);
            }
        }
 
        private int code;
 
        H5O_type(int layout_type) {
            this.code = layout_type;
        }
 
        public int getCode() {
            return this.code;
        }
 
        public static H5O_type get(int code) {
            return lookup.get(code);
        }
    }
 
    //将读出的数据写到本地
    public static void writeLocalExcel(Sensor[] dataSensors, String datasetName, long dims) {
        //测试数据写出 io
        String url = "D:/hdf5_write_txt/";
        String dsetUrl = datasetName;
        String path = url + dsetUrl + ".txt";
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        } else {
            file = new File(path);
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //执行遍历写出
        try {
            PrintWriter pw = new PrintWriter(file, "UTF-8");
            pw.append(
                    "trading_day, updatetime, instrument_id, gap_number, reserve "
            );
            pw.print("\n");
            for (int i = 0; i < dims; i++) {
                StringBuffer sb = new StringBuffer("");
                //当前获取的字段值
                Sensor data = dataSensors[i];
                if (i < dataSensors.length - 1) {
                    sb.append(data).append("," + "\t");
                } else {
                    sb.append(data).append(" ");
                }
                //此时不做判断会发生空指针异常 定义的h5文件行数固定,各个文件行数不同
                if (null != data) {
                    pw.print(data.toString() + "\n");
                }
            }
            pw.close();
        } catch (FileNotFoundException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        H5ReadHelper.ReadDataset("D:/tongzhou.h5");
    }
}