有没有人知道一个简单的库来从.NET框架中的HDF files读取数据?
答案 0 :(得分:2)
刚才我处理这个问题时,我找不到HDF4 for .NET的任何内容。 (我认为这是有道理的,因为HDF4不再受到支持,HDF4最早是在1995年左右创建的。)
我最终做的是滚动我自己的库来执行非常具体的命令来传达HDF文件。其中大部分都不值得分享,但以下内容可能有助于P / Invoke签名(并非所有签名都可能已经过测试等)。
public class HDF4
{
#region DLL Imports
private const string HDF4DLL = "hm421m.dll";
#region file / dataset access
[DllImport(HDF4DLL)]
public static extern int SDcreate(int sd_id, string name, DataTypeDefinitions data_type, int rank, int[] dimsizes);
[DllImport(HDF4DLL)]
public static extern int SDstart(string filename, AccessCodes access_mode);
[DllImport(HDF4DLL)]
public static extern short SDendaccess(int sds_id);
[DllImport(HDF4DLL)]
public static extern short SDend(int sd_id);
#endregion
#region data access
[DllImport(HDF4DLL)]
public static extern int SDselect(int sd_id, int sds_index);
[DllImport(HDF4DLL)]
public static extern int SDreaddata(int sds_id, int[] start, int[] stride, int[] edge, IntPtr buffer);
[DllImport(HDF4DLL)]
public static extern int SDwritedata(int sds_id, int[] start, int[] stride, int[] edge, IntPtr buffer);
[DllImport(HDF4DLL)]
public static extern short SDgetdatastrs(int sds_id, StringBuilder label, StringBuilder unit, StringBuilder format, int length);
[DllImport(HDF4DLL)]
public static extern short SDsetdatastrs(int sds_id, string label, string unit, string format, string coordsys);
#endregion
#region dim
[DllImport(HDF4DLL)]
public static extern int SDgetdimid(int sds_id, int dim_index);
[DllImport(HDF4DLL)]
public static extern short SDdiminfo(int dim_id, StringBuilder name, out int size, out DataTypeDefinitions datay_type, out int num_attrs);
[DllImport(HDF4DLL)]
public static extern short SDgetdimstrs(int dim_id, StringBuilder label, StringBuilder unit, StringBuilder format, int length);
[DllImport(HDF4DLL)]
public static extern short SDgetdimscale(int dim_id, IntPtr data);
[DllImport(HDF4DLL)]
public static extern short SDsetdimname(int dim_id, string dim_name);
[DllImport(HDF4DLL)]
public static extern short SDsetdimscale(int dim_id, int count, DataTypeDefinitions data_type, IntPtr data);
[DllImport(HDF4DLL)]
public static extern short SDsetdimstrs(int dim_id, string label, string unit, string format);
#endregion
#region lookups / checks
[DllImport(HDF4DLL)]
public static extern int SDcheckempty(int sds_id, out bool emptySDS);
[DllImport(HDF4DLL)]
public static extern int SDnametoindex(int sd_id, string sds_name);
[DllImport(HDF4DLL)]
public static extern int SDfileinfo(int sd_id, out int num_datasets, out int num_global_attrs);
[DllImport(HDF4DLL)]
public static extern short SDgetinfo(int sds_id, StringBuilder sds_name, out int rank, [In, Out] int[] dimsizes, out DataTypeDefinitions data_type,
out int num_attrs);
[DllImport(HDF4DLL)]
public static extern bool SDiscoordvar(int sds_id);
#endregion
#region attr
[DllImport(HDF4DLL)]
public static extern int SDfindattr(int obj_id, string attr_name);
[DllImport(HDF4DLL)]
public static extern short SDattrinfo(int obj_id, int attr_index, StringBuilder attr_name, out DataTypeDefinitions data_type, out int count);
[DllImport(HDF4DLL)]
public static extern short SDreadattr(int obj_id, int attr_index, StringBuilder attr_buff);
[DllImport(HDF4DLL)]
public static extern short SDsetattr(int obj_id, string attr_name, DataTypeDefinitions data_type, int count, StringBuilder values);
#endregion
#endregion
#region Enums / Consts
public const uint DFNT_NATIVE = 4096;
public const int MAX_VAR_DIMS = 32;
[Flags]
public enum DataTypeDefinitions : uint
{
DFNT_CHAR8 = 4,
DFNT_CHAR = 4,
DFNT_UCHAR8 = 3,
DFNT_UCHAR = 3,
DFNT_INT8 = 20,
DFNT_UINT8 = 21,
DFNT_INT16 = 22,
DFNT_UINT16 = 23,
DFNT_INT32 = 24,
DFNT_UINT32 = 25,
DFNT_FLOAT32 = 5,
DFNT_FLOAT64 = 6,
DFNT_NINT8 = DFNT_NATIVE | DFNT_INT8,
DFNT_NUINT8 = DFNT_NATIVE | DFNT_UINT8,
DFNT_NINT16 = DFNT_NATIVE | DFNT_INT16,
DFNT_NUINT16 = DFNT_NATIVE | DFNT_UINT16,
DFNT_NINT32 = DFNT_NATIVE | DFNT_INT32,
DFNT_NUINT32 = DFNT_NATIVE | DFNT_UINT32,
DFNT_NFLOAT32 = DFNT_NATIVE | DFNT_FLOAT32,
DFNT_NFLOAT64 = DFNT_NATIVE | DFNT_FLOAT64
}
public enum AccessCodes
{
DFACC_READ = 1,
DFACC_WRITE = 2,
DFACC_CREATE = 4,
DFACC_ALL = 7,
DFACC_RDONLY = 1,
DFACC_RDWR = 3
}
#endregion
#region Helper Functions
public static double[] SDgetdimscaledouble(int dim_id, int size)
{
double d = 0;
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(d) * size);
SDgetdimscale(dim_id, p);
double[] dest = new double[size];
Marshal.Copy(p, dest, 0, size);
Marshal.FreeHGlobal(p);
return dest;
}
public static void SDsetdimscaledouble(int dim_id, double[] d)
{
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(d[0])*d.Length);
Marshal.Copy(d, 0, p, d.Length);
int res = SDsetdimscale(dim_id, d.Length, DataTypeDefinitions.DFNT_FLOAT64, p);
Marshal.FreeHGlobal(p);
}
public static double SDreaddouble(int sds_id, int[] start, int[] edge)
{
double d = 0;
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(d));
SDreaddata(sds_id, start, null, edge, p);
double[] dest = new double[1];
Marshal.Copy(p, dest, 0, 1);
d = dest[0];
Marshal.FreeHGlobal(p);
return d;
}
public static void SDwritedouble(int sds_id, int[] start, int[] edge, double d)
{
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(d));
double[] a = new double[1];
a[0] = d;
Marshal.Copy(a, 0, p, 1);
int res = SDwritedata(sds_id, start, null, edge, p);
Marshal.FreeHGlobal(p);
}
#endregion
}
因此,您可以为文件,数据集,维度,属性等创建对象。对于文件,这是一个片段:
public class HDFFile : IDisposable
{
// snip
public static HDFFile New(string fullfilename)
{
HDFFile hdf = new HDFFile(fullfilename);
hdf._sdId = HDF4.SDstart(fullfilename, HDF4.AccessCodes.DFACC_CREATE);
return hdf;
}
public static HDFFile Open(string fullfilename)
{
HDFFile hdf = new HDFFile(fullfilename);
hdf._sdId = HDF4.SDstart(fullfilename, HDF4.AccessCodes.DFACC_RDWR);
if (hdf._sdId == -1)
throw new Exception("Could not open " + fullfilename);
hdf.Load();
return hdf;
}
private void Load()
{
int num_ds = 0;
int num_global = 0;
HDF4.SDfileinfo(_sdId, out num_ds, out num_global);
for (int i = 0; i < num_ds; i++)
{
HDFDataSet hds = HDFDataSet.Load(_sdId, i);
if (!string.IsNullOrEmpty(hds.Name))
_dataSets.Add(hds);
}
_attributes = HDFAttribute.Load(_sdId, num_global);
}
// snip
}
答案 1 :(得分:1)
您发布的网站上有一个不受支持的解决方案
ftp://ftp.hdfgroup.uiuc.edu/pub/outgoing/hdf5/HDF5dotNetEnv/
答案 2 :(得分:0)
更好的方法是从HDF对象本身抽象元数据; HDF小组正在开发一种映射工具,可以转储有关如何从HDF文件(即SDS,RIS,VData等)获取原始数据类型的信息,这样您就可以编写自己的读取器而无需使用HDF / Net CDF库。