笔者在MyEclipse中进行HDF文件的读写,遇到了java.lang.UnsatisfiedLinkError:no jhdf5 in java.library.path的问题。笔者详细地记录了整个过程,如只需此问题的解决,可跳过前面部分直接找该问题解决方法。
1.MyEclipse新建Java工程,命名为HDF_Dataset
2.添加所需jar包 jarhdf5-3.2.1.jar slf4j-api-1.7.5.jar slf4j-nop-1.7.5.jar
工程名右键选择新建文件夹,命名为lib
将三个jar包拷贝到lib下
jar包右键--Build Path--Add to Build Path
3.编辑代码
新建Class文件,命名为H5Ex_D_ReadWrite,放到包examples.datasets中
代码如下:
package examples.datasets;
import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;
public class H5Ex_D_ReadWrite {
private static String FILENAME = "/home/hadoop/Documents/HDF5/test.h5";
private static String DATASETNAME = "DS1";
private static final int DIM_X = 4;
private static final int DIM_Y = 7;
private static final int RANK = 2;
private static void WriteDataset() {
int file_id = -1;
int filespace_id = -1;
int dataset_id = -1;
long[] dims = { DIM_X, DIM_Y };
int[][] dset_data = new int[DIM_X][DIM_Y];
// Initialize data.
for (int indx = 0; indx < DIM_X; indx++)
for (int jndx = 0; jndx < DIM_Y; jndx++)
dset_data[indx][jndx] = indx * jndx - jndx;
// Create a new file using default properties.
try {
file_id = H5.H5Fcreate(FILENAME, HDF5Constants.H5F_ACC_TRUNC, //创建文件,指定文件名,文件存取模式,文件创建特性列表,文件存取特性列表
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
// Create dataspace. Setting maximum size to NULL sets the maximum
// size to be the current size.
try { //H5Screate_simple新建一个数据空间并打开它等待接收数据
filespace_id = H5.H5Screate_simple(RANK, dims, null);
}
catch (Exception e) {
e.printStackTrace();
}
// Create the dataset. We will use all default properties for this example.
try {
if ((file_id >= 0) && (filespace_id >= 0)) //H5Dcreate 新建一个数据集file_id
dataset_id = H5.H5Dcreate(file_id, DATASETNAME,
HDF5Constants.H5T_STD_I32LE, filespace_id,
HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT, HDF5Constants.H5P_DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
// Write the data to the dataset.
try {
if (dataset_id >= 0) //H5.H5Dwrite将dset_data中的数据对象写入文件中
H5.H5Dwrite(dataset_id, HDF5Constants.H5T_NATIVE_INT,
HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, dset_data);
}
catch (Exception e) {
e.printStackTrace();
}
// End access to the dataset and release resources used by it.
try {
if (dataset_id >= 0)
H5.H5Dclose(dataset_id); //关闭数据集
}
catch (Exception e) {
e.printStackTrace();
}
try {
if (filespace_id >= 0)
H5.H5Sclose(filespace_id); //释放数据空间
}
catch (Exception e) {
e.printStackTrace();
}
// Close the file.
try {
if (file_id >= 0)
H5.H5Fclose(file_id);//关闭文件,写操作结束
}
catch (Exception e) {
e.printStackTrace();
}
}
private static void ReadDataset() {
int file_id = -1;
int dataset_id = -1;
int[][] dset_data = new int[DIM_X][DIM_Y];
// Open file using the default properties.
try { //H5.H5Fopen打开一个已存在的文件
file_id = H5.H5Fopen(FILENAME, HDF5Constants.H5F_ACC_RDWR,
HDF5Constants.H5P_DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
// Open dataset using the default properties.
try {
if (file_id >= 0) //H5.H5Dopen打开数据集
dataset_id = H5.H5Dopen(file_id, DATASETNAME, HDF5Constants.H5P_DEFAULT);
}
catch (Exception e) {
e.printStackTrace();
}
// Read the data using the default properties.
try {
if (dataset_id >= 0) //H5Dread读数据到dset_data中
H5.H5Dread(dataset_id, HDF5Constants.H5T_NATIVE_INT,
HDF5Constants.H5S_ALL, HDF5Constants.H5S_ALL,
HDF5Constants.H5P_DEFAULT, dset_data);
}
catch (Exception e) {
e.printStackTrace();
}
// Output the data to the screen.
System.out.println(DATASETNAME + ":");
for (int indx = 0; indx < DIM_X; indx++) {
System.out.print(" [ ");
for (int jndx = 0; jndx < DIM_Y; jndx++)
System.out.print(dset_data[indx][jndx] + " ");
System.out.println("]");
}
System.out.println();
// Close the dataset.
try {
if (dataset_id >= 0)
H5.H5Dclose(dataset_id);
}
catch (Exception e) {
e.printStackTrace();
}
// Close the file.
try {
if (file_id >= 0)
H5.H5Fclose(file_id);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
H5Ex_D_ReadWrite.WriteDataset();
H5Ex_D_ReadWrite.ReadDataset();
}
}
根据错误类型java.lang.UnsatisfiedLinkError,我们知道这是Link错误,即程序运行时找不到链接库。因此还需要一步:
4.add the HDF5 JNI library to your path
在Linux中,需要的是so文件;Windows中是dll文件
在命令行下,Linux通过设置LD_LIBRARY_PATH,Windows设置PATH 参考:https://support.hdfgroup.org/products/java/release/download.html#script 截图如下:
重点说在MyEclipse中:
Run---Run Configurations
设置Arguments--VM arguments:-Djava.library.path=libjhdf5.so文件所在目录,然后点击右下角Run 运行即可。
再运行,就会得到正确结果:
在/home/hadoop/Documents/HDF5下可以看到test.h5文件
用HDFView可以查看该文件:
补充:
文件下载:
在https://support.hdfgroup.org/products/java/release/download.html#bldsrc中下载HDFJava 3.2.1
解压缩之后运行.sh文件
在lib文件夹中有要用到的jar包和libjhd5.so 。注意,将下图中的libjhdf5.so.3.2.1拷贝到指定文件夹(/home/hadoop/Documents/linux)改名!改名为libjhd5.so
注意:
要用新版jar包,旧版jar包有ncsa前缀,新版没有。
旧版:
import ncsa.hdf.hdf5lib.H5;
import ncsa.hdf.hdf5lib.HDF5Constants;
而最新的jar包没有ncsa,即:
import hdf.hdf5lib.H5;
import hdf.hdf5lib.HDF5Constants;
笔者很详细地记录了整个过程,因为解决java.lang.UnsatisfiedLinkError着实费了很多功夫,因为用的是旧版jar包和新版libjhdf5.so文件,一直没成功,后来想到了这个原因,解决了问题。
也可以直接下载需要的三个jar包和so文件:
http://download.csdn.net/detail/luoying_1993/9866509