NetCDF 4.3.17 の時点で、 と の実装はVariable.read()
、Variable.read(Section)
構造体の配列のメンバーを読み取るときにかなり異なり、どちらも API ドキュメントに準拠していません。以下に回避策を示します。
説明のために、次のものがあるとしましょう。
Structure {
int foo;
:_Unsigned = "true";
int bar;
:_Unsigned = "true";
} example(24);
これは、構造体の名前が付けられた 24 要素の配列example
であり、各構造体には 2 つのメンバーfoo
とが含まれbar
ます。foo
次のようにメンバーへの参照を取得するとします。
final Variable fooVariable = netcdfFile.findVariable("/blah/example.foo");
を呼び出すと、配列内の要素である構造体の一部であるfooVariable.read()
ため、最初の値が返されると API ドキュメントに記載されています。foo
これは起こることではありません。代わりに、ライブラリは実際に巧妙な読み取りを行いfoo
、すべての構造体から値の単一の配列としてメンバーを返しfoo
ます。これは私が望む動作です。
残念ながら、このfooVariable.read(Section)
実装には と同じように巧妙なコードがfooVariable.read()
なく、代わりに をスローするように記述されていUnsupportedOperationException
ます。(チェックが追加されていないため、コードはそれほど遠くまで到達せずInvalidRangeException
、指定されたものが無効であると見なされるため、 をスローしSection
ます。これは残念です。(チェックを追加して を回避すると)実装InvalidRangeException
からの巧妙なコード1 行に 1 つのメソッド引数のみを挿入してVariable.read()
も、同様にうまく機能します。Variable.read(Section)
の巧妙なコードを使用して、Variable.read()
この問題を回避するメソッドを作成し、呼び出し元が任意の変数を含む配列のセクションを要求できるようにしました。変数が配列内の構造体のメンバーである場合、そのメンバーの部分範囲のみが読み取られ、構造体メンバーfooVariable.read(Section)
と同じ動作を持つメソッドの別のバージョンが効果的に作成されます。fooVariable.read()
/**
* Reads an array of data from the provided NetCDF variable. If the variable is a member of a structure, that member is read
* from all the structures in the array and returned as a single array containing that member from each structure.
* @param variable The NetCDF variable to read.
* @param section The section indicating the element of the array to read
* @param indexEnd The ending source index, exclusive, or -1 if all available values should be read.
* @return An array representing the requested range of values read for the given variable.
* @throws IOException if there is an error reading the data.
*/
public static Array readArray(final Variable variable, final Section section) throws IOException, InvalidRangeException {
if (variable.isMemberOfStructure()) { //if the variable is member of a structure
final Structure parentStructure = variable.getParentStructure().select(variable.getShortName()); //select just the member variable
final ArrayStructure arrayStructure = (ArrayStructure) parentStructure.read(section); //read the array of structures
return arrayStructure.extractMemberArray(arrayStructure.findMember(variable.getShortName())); //extract just the member into an array
} else { //if the variable is not a member of a structure
return variable.read(section); //just read the section directly from the variable
}
}
この問題 (現在は NRW-974703 として識別されています) をUnidata NetCDF Supportで報告しました。最初に、これらの方法は HDF5 には適用されず、Unidata 独自の NetCDF ファイル形式にのみ適用されると言われました。(これは完全に間違っています。) その後、私は Java NetCDF API を理解していないと言われました (ただし、前の回答から、Unidata ライブラリを正確に理解していない人は誰なのか疑問に思います)。特定の問題コードを追跡し、上記の回避策を提供した後、Unidata からまだ応答を受け取っていません。