HDF5 : 可変長文字列の書き込み ― 2013年02月14日 21:35
可変長な文字列の書き込みと読み込みについて
文字の書き込みと読み込みについては、一度固定長の文字列について言及したが、今回は可変長の文字列について
書き込みには"H5DataSetId"クラス("H5DataSetId"クラスを作成するには”H5DataSpaceId”クラスと"H5DataTypeId"クラスが必要)と"H5DataTypeId"クラスが必要になる点はかわらない。
違う点について、
固定長時は文字列を文字列データとして扱うために、byte配列に変換、変換データを用いて"H5DataType"クラスのサイズ設定と”write<>”メソッドをbyte型にて実行した。
可変長時はC++などで使用するポインタを使用(といってもポインタを意識するような使い方はしなくてもよい)して、"H5DataSetId"クラスの作成や"write<>"メソッドの実行を行う。
"H5DataSpaceId"クラスの作成については、今までと変わらないので、固定長のものを参考に、ここでは割愛。
"H5DataTypeId"クラスを作成する場合は、"H5T"クラスの"create"メソッドを使用するが、引数の"size"(int型)に-1を指定する。これは、可変長の文字列を使用するときには必ず行う。
次に文字列のデータの作成。文字列データへの変換には"UTF8Encoding"クラスなどのEncoding系クラスを使用せず、System.Runtime.InteropServices空間にある"Marshal"クラスにある"StringToHGlobalAnsi"メソッドを使用する。引数は"string"クラス、戻り値は"IntPtr"構造体。要するに、アンマネージ領域に文字列データを用意しておき、ポインタを使用して書き込む。
文字の書き込みと読み込みについては、一度固定長の文字列について言及したが、今回は可変長の文字列について
書き込みには"H5DataSetId"クラス("H5DataSetId"クラスを作成するには”H5DataSpaceId”クラスと"H5DataTypeId"クラスが必要)と"H5DataTypeId"クラスが必要になる点はかわらない。
違う点について、
固定長時は文字列を文字列データとして扱うために、byte配列に変換、変換データを用いて"H5DataType"クラスのサイズ設定と”write<>”メソッドをbyte型にて実行した。
可変長時はC++などで使用するポインタを使用(といってもポインタを意識するような使い方はしなくてもよい)して、"H5DataSetId"クラスの作成や"write<>"メソッドの実行を行う。
"H5DataSpaceId"クラスの作成については、今までと変わらないので、固定長のものを参考に、ここでは割愛。
"H5DataTypeId"クラスを作成する場合は、"H5T"クラスの"create"メソッドを使用するが、引数の"size"(int型)に-1を指定する。これは、可変長の文字列を使用するときには必ず行う。
H5DataTypeId typeID = H5T.create(H5T.CreateClass.STRING,-1);"H5DataSetId"クラスは上記の"H5DataSpaceId"クラスと"H5DataTypeId"で作成。作成方法は今までと同じなので割愛。
次に文字列のデータの作成。文字列データへの変換には"UTF8Encoding"クラスなどのEncoding系クラスを使用せず、System.Runtime.InteropServices空間にある"Marshal"クラスにある"StringToHGlobalAnsi"メソッドを使用する。引数は"string"クラス、戻り値は"IntPtr"構造体。要するに、アンマネージ領域に文字列データを用意しておき、ポインタを使用して書き込む。
IntPtr stringPtr = Marshal.StringToHGlobalAnsi( stringValue );これで、"H5D"クラスの"write<>"メソッドを実行する。ジェネリックの指定はもちろん"IntPtr"構造体を使用する。
H5Array<IntPtr> dataArray = new H5Array<IntPtr>( new []{stringPtr} );使用後は、"close"メソッドができるものは行う。"IntPtr"構造体については"Marshal"クラスにある"FreeHGlobal"メソッドを使用してメモリを開放する。引数は"IntPtr"構造体。
H5D.write<IntPtr>( datasetID, ftypeID, dataArray ) );
Marshal.FreeHGlobal( stringPtr );
以下、サンプル。H5FileId fileID = H5F.create("C:\\Test.hdf5" , H5F.CreateMode.ACC_TRUNC );
H5DataTypeId typeID = H5T.create(H5T.CreateClass.STRING,-1); H5DataSetId datasetID = H5D.create( fileID, "VariableStr", typeID, spaceID ); string stringValue = "This is TestString.";
IntPtr stringPtr = Marshal.StringToHGlobalAnsi( stringValue );
H5Array<IntPtr> dataArray = new H5Array<IntPtr>( new []{stringPtr} );
H5D.write<IntPtr>( datasetID, typeID, dataArray ) );
H5D.close( datasetID );
H5T.close( typeID );
H5S.close( spaceID );
H5F.close( fileID );
Marshal.FreeHGlobal( stringPtr );
最近のコメント