c# hdf5 写string_关于C#中读取HDF4文件数据的说明
HDF4也被稱為HDF(Hierarchical Data Format),可以存儲不同類型的圖像和數碼數據的文件格式,并且可以在不同類型的機器上傳輸,同時還有統一處理這種文件格式的函數庫。隨著技術的發展,現存在兩個完全不同的HDF文件版本:HDF4和HDF5,其中HDF4是第一個HDF版本。我們可以通過訪問HDF4的官方網站(http://www.hdfgroup.org/products/hdf4/)查看其詳細介紹。
如果只是需要查看HDF4文件數據的話,我們可以從官網上下載并安裝HDFView(一個簡單的HDF文件查看工具):
但是如果需要通過編程手段讀寫HDF4文件數據的話,我們就必須先從官網上下載并安裝HDF4的函數庫,然后再編程調用該函數庫來實現對其的讀寫。
以下介紹如何通過C#方式讀取HDF4文件的屬性和數據。
一、安裝HDF4函數庫:
在HDF4官網下載頁(http://www.hdfgroup.org/release4/obtain.html)下載并安裝HDF4函數庫。官網提供了多個系統平臺的編譯版本,在這里我們選擇“Windows (32-bit)”平臺:
如在安裝過程中發現環境變量無法寫入,我們可以忽略設置環境變量選項。
二、引用HDF4函數庫:
從官網中我們可以發現,現在的HDF4函數庫只有提供C++和Fortran訪問的版本,要想在C#程序中使用的話,我們需要通過DllImport方式引入。HDF4的函數庫主要包含在hdf.dll和mfhdf.dll這兩個庫中,而常用來讀取HDF4中數據的SD接口則在mdhdf.dll庫中。
// 定義HDF4 SD接口函數庫的文件位置
public const string MFHDF4_DLL = @"C:\Program Files (x86)\HDF_Group\HDF\4.2.11\bin\mfhdf.dll";
// 引入SDstart方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDstart", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDstart(string filename, int access_mode);
// 引入SDfindattr方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDfindattr", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDfindattr(int obj_id, string attr_name);
// 引入SDreadattr方法(字符串類型屬性)
[DllImport(MFHDF4_DLL, EntryPoint = "SDreadattr", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDreadattr(int obj_id, int attr_index, StringBuilder attr_buffer);
// 引入SDreadattr方法(單精度浮點類型屬性)
[DllImport(MFHDF4_DLL, EntryPoint = "SDreadattr", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDreadattr(int obj_id, int attr_index, float[] attr_buffer);
// 引入SDnametoindex方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDnametoindex", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDnametoindex(int sd_id, string sds_name);
// 引入SDselect方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDselect", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDselect(int sd_id, int sds_index);
// 引入SDgetinfo方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDgetinfo", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDgetinfo(int sds_id, StringBuilder sds_name, int[] rank, int[] dimsizes, int[] ntype, int[] num_attrs);
// 引入SDreaddata方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDreaddata", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDreaddata(int sds_id, int[] start, int[] stride, int[] edge, short[,] buffer);
// 引入SDendaccess方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDendaccess", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDendaccess(int sds_id);
// 引入SDend方法
[DllImport(MFHDF4_DLL, EntryPoint = "SDend", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDend(int sd_id);
以上我們通過DllImport的方式引入讀取HDF4文件所需要用到的相關SD接口函數,其中EntryPoint屬性為對應的函數名稱,CallingConvention屬性必須設置為CallingConvention.Cdecl。由于個別函數返回的數據是通過指針引用在函數參數中的,因此我們需要通過StringBuilder來接收字符串數據,通過值類型數組(如float[]、int[]、short[]等)來接收數值型數據和數組型數據(不能通過ref或out參數返回)。
三、讀取HDF4屬性和數據:
// 要讀取的HDF4文件
string hdf4File = "C:/test.hdf";
// 字符串類型屬性
string sensor;
// 單精度浮點類型屬性
float slope;
// 數據行數
int row;
// 數據列數
int column;
// 數據集數據
short[,] data;
// 函數調用狀態
int status;
// 只讀方式打開HDF4文件
int sd_id = SDstart(hdf4File, 1);
if (sd_id != -1)
{
// 查找屬性Sensor的索引號
int attr_index = SDfindattr(sd_id, "Sensor");
if (attr_index != -1)
{
// 讀取Sensor屬性,通過StringBuilder接收字符串數據
StringBuilder buffer = new StringBuilder();
status = SDreadattr(sd_id, attr_index, buffer);
if (status != -1)
{
sensor = buffer.ToString();
}
}
// 查找屬性Slope的索引號
attr_index = SDfindattr(sd_id, "Slope");
if (attr_index != -1)
{
// 讀取Slope屬性,通過float[]接收單精度浮點數據
float[] buffer = new float[1];
status = SDreadattr(sd_id, attr_index, buffer);
if (status != -1)
{
slope = buffer[0];
}
}
// 查找數據集DATA的索引號
int sds_indes = SDnametoindex(sd_id, "DATA");
// 選中數據集
int sds_id = SDselect(sd_id, sds_indes);
if (sds_id != -1)
{
// 數據集名稱
StringBuilder sds_name = new StringBuilder();
// 秩數
int[] rank = new int[1];
// 行列數
int[] dimsizes = new int[2];
// 數據類型
int[] ntype = new int[1];
// 屬性數目
int[] num_attrs = new int[1];
// 讀取數據集信息
status = SDgetinfo(sds_id, sds_name, rank, dimsizes, ntype, num_attrs);
if (status != -1)
{
row = dimsizes[0];
column = dimsizes[1];
// 讀取數據集所有數據
short[,] buffer = new short[row, column];
status = SDreaddata(sds_id, new int[] { 0, 0 }, null, new int[] { row, column }, buffer);
if (status != -1)
{
data = buffer;
}
}
// 結束數據集訪問
status = SDendaccess(sds_id);
}
// 關閉HDF4文件
status = SDend(sd_id);
}
從以上方法中可以看出,雖然HDF4官方并沒有提供可直接讓C#訪問的類庫,但我們還是可以基于DllImport這種靜態函數引入的方式對其進行訪問。
總結
以上是生活随笔為你收集整理的c# hdf5 写string_关于C#中读取HDF4文件数据的说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDFView的闪退问题
- 下一篇: Word多级标题出现黑块的解决思路