Artavazd Balayan’s answer is pointing into the right direction. A ByteBuffer
allows to interpret its contents as Big Endian or Little Endian, as you wish and is the right tool for the job.
But when you use it, there is no need for DataInputStream
anymore. You can use the ByteBuffer
for the transfer directly.
A Java code handling it efficiently may look like:
static float[][] bilToArray(Path dataFile, int nRows, int nCols) throws IOException {
try(ReadableByteChannel fch = Files.newByteChannel(dataFile, StandardOpenOption.READ)){
float[][] matrix = new float[nRows][nCols];
ByteBuffer bb = ByteBuffer.allocateDirect(Float.BYTES*nRows*nCols);
while(bb.hasRemaining()) if(fch.read(bb)<0) throw new EOFException();
bb.flip();
FloatBuffer fb = bb.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
for(float[] row: matrix) fb.get(row);
return matrix;
}
}
If the file is very large and you know that it is always in the default file system, you may even use a Memory-mapped file:
static float[][] bilToArray(Path dataFile, int nRows, int nCols) throws IOException {
try(FileChannel fch = FileChannel.open(dataFile, StandardOpenOption.READ)) {
float[][] matrix = new float[nRows][nCols];
ByteBuffer bb = fch.map(FileChannel.MapMode.READ_ONLY, 0, Float.BYTES*nRows*nCols);
FloatBuffer fb = bb.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
for(float[] row: matrix) fb.get(row);
return matrix;
}
}
Converting this to Scala shouldn’t be so hard.