Other classes needed when writing an IOSP
To implement an IOSP, you will likely need to be familiar with the following classes:
RandomAccessFile
The class ucar.unidata.io.RandomAccessFile
is a cover for java.io.RandomAccessFile
, which it (usually) uses underneath.
It additionally implements user-settable buffer sizes, files with both big and little endianness, reading multiple Charsets
, and several other methods to improve the API.
There are subclasses of RandomAccessFile
such as HTTPRandomAccessFile
and InMemoryRandomAccessFile
, which deal with remote HTTP files
and memory resident files. Use of these subclasses is transparent to an IOSP.
A summary of the public methods that may useful to an IOSP:
public class ucar.unidata.io.RandomAccessFile {
public static final int BIG_ENDIAN;
public static final int LITTLE_ENDIAN;
// Constructors
public RandomAccessFile(String location, String mode) throws IOException;
public RandomAccessFile(String location, String mode, int buffer_size) throws IOException;
public void close() throws IOException;
public String getLocation();
public void order(int endian); // set to BIG_ENDIAN or LITTLE_ENDIAN
// file position
public long getFilePointer() throws IOException;
public long length() throws IOException;
public void seek(long filePos) throws IOException;
public int skipBytes(int nbytes) throws IOException;
// read
public int read() throws IOException;
public int read(byte[] arr) throws IOException;
public int read(byte[] arr, int start, int n) throws IOException;
public byte readByte() throws IOException;
public final double readDouble() throws IOException;
public final void readDouble(double[] arr, int start, int n) throws IOException;
public final float readFloat() throws IOException;
public final void readFloat(float[] arr, int start, int n) throws IOException;
public final int readInt() throws IOException;
public final void readInt(int[] arr, int start, int n) throws IOException;
public final long readLong() throws IOException;
public final void readLong(long[]
arr, int start, int n) throws IOException;
public final short readShort() throws IOException;
public final void readShort(short[] arr, int start, int n) throws IOException;
// read unsigned, promote to int
public final int readUnsignedShort() throws IOException;
public final int readUnsignedByte() throws IOException;
// read Strings
public final String readLine() throws IOException;
public final String readUTF() throws IOException;
public String readString(int nbytes) throws IOException;
}
Array
A ucar.array.Array
is an abstract, immutable object which allows working with multidimensional arrays in a type and rank general way.
It replaces the deprecated ucar.ma2.array
package.
It is implemented by ArrayByte
, ArrayChar
, ArrayDouble
, ArrayFloat
, ArrayInteger
, ArrayLong
, ArrayShort
, and ArrayString
.
Some useful Array
methods include:
public abstract class Array<T> implements Iterable<T> {
public abstract T get(int... index); // Get the element indicated by the list of multidimensional indices.
public abstract T get(Index index); // Get the element indicated by Index
public T getScalar(); // Get the first element of the Array
public ArrayType getArrayType(); // Get the datatype for this array
public boolean isVlen();
public Index getIndex(); // Get an Index that can be used instead of an int[]
public int getRank();
public int[] getShape();
public Section getSection(); // Returns a list of Ranges, one for each dimenstion
public long length(); // Get the total number of elements in the array. Excludes vlen dimensions.
}
The ucar.array.Arrays
class contains an number of static function for creating and using Array
objects:
public static <T> Array<T> factory(ArrayType dataType, int[] shape, Storage<T> storage);
public static <T> Array<T> factory(ArrayType dataType, int[] shape, Object dataArray);
public static <T> Array<T> factory(ArrayType dataType, int[] shape);
public static <T> Array<T> factoryCopy(ArrayType dataType, int[] shape, List<Array<t>> dataArrays);
public static <T> Object combine(ArrayType dataType, int[] shape, Object dataArray);
public static <T> Array<T> factoryArrays(ArrayType dataType, int[] shape, List<Array<?>> dataArrays);
public static <T> Array<T> flip(Array<t> org, int dim);
public static Array transpose(<T> Array<T> org, int dim1, int dim2);
public static Array <T> permute(<T> Array<T> org, int[]) dims;
public static <T> Array<T> reshape(<T> Array<T> org, int[] shape);
public static Array <T> reduce(<T> Array<T> org, );
public static Array <T> reduce<T>(<T> Array<T> org, int dim);
public static Array <T> section(<T> Array<T> org, Section section) throws InvalidRangeException;
public static Array <T> slice(<T> Array<T> org, int dim, int value);
public static long computerSize(int[] shape);
public static int[] removeVlen(int[] shape);
public static Array<Double> toDouble(Array<?> array);
public static MinMax getMinMaxSkipMissingData(Array<? extends Number> a, @Nullable IsMissingEvaluator eval);
public static Array<Double> makeArray(int[] shape, int npts, double start, double incr);
}
Typically an IOSP will create the underlying primitive Java array, then wrap it in an Array
using Arrays.factory
, for example:
// To make an Array object for data in a Variable, v:
int size = (int) v.getSize();
short[] jarray = new short[size];
// ...
// read data into jarray
// ...
Array data = Arrays.factory(v.getArrayType(), v.getShape(), jarray);
A ucar.array.Section
is an immutable container for a List
of Range
objects, replacing the deprecated ucar.ma2.Section
package.
A section can be used to read only wanted data, using Arrays.section(Array<T> org, Section section)
.
Once you have an Array
, you can iterate over each element using the built-in iterator
:
Iterator<Float> it = data.iterator();
while (it.hasNext()) {
float val = it.next();
// do something
}
You can also access Array
values by index:
float val = data.get(5);
val = data.get(data.getIndex());
There is also StructureDataArray
, but this is handled differently from the numeric and String
types.
See StructureDataArrays.
ArrayType
The class ucar.array.ArrayType
is a type-safe enumeration of data types for the CDM and include the following types:
public enum ArrayType {
BOOLEAN("boolean", 1, boolean.class, false), //
BYTE("byte", 1, byte.class, false), //
CHAR("char", 1, char.class, false), //
SHORT("short", 2, short.class, false), //
INT("int", 4, int.class, false), //
LONG("long", 8, long.class, false), //
FLOAT("float", 4, float.class, false), //
DOUBLE("double", 8, double.class, false), //
// object types
SEQUENCE("Sequence", 4, Iterator.class, false), // 32-bit index
STRING("String", 4, String.class, false), // 32-bit index
STRUCTURE("Structure", 0, StructureData.class, false), // size unknown
ENUM1("enum1", 1, byte.class, false), // byte
ENUM2("enum2", 2, short.class, false), // short
ENUM4("enum4", 4, int.class, false), // int
OPAQUE("opaque", 1, ByteBuffer.class, false), // size unknown, byte blobs;
OBJECT("object", 1, Object.class, false), // size unknown, use with ucar.ma2.Array
UBYTE("ubyte", 1, byte.class, true), // unsigned byte
USHORT("ushort", 2, short.class, true), // unsigned short
UINT("uint", 4, int.class, true), // unsigned int
ULONG("ulong", 8, long.class, true); // unsigned long
}