Java: How to "crop" an array of bytes?

So, I have a code that reads a certain number of bytes from a file and returns a resulting array of bytes (this is mainly used to split files for sending over the network in the form of (ultimately) base64 based asc64 code).

It works great, except that when you create the last fragment of a file, it is not a complete fragment. Consequently, the resulting byte array is not populated. However, this is a constant size, which means that the file is reassembled, a whole bunch of additional data is added (possibly 0).

How can I make sure that the byte [] for the last fragment of the file really contains only the data that it needs? The code is as follows:

private byte[] readData(File f, int startByte, int chunkSize) throws Exception { RandomAccessFile raf = new RandomAccessFile(f, "r"); raf.seek(startByte); byte[] data = new byte[chunkSize]; raf.read(data); raf.close(); return data; } 

So, if chunkSize is larger than the remaining bytes in the file, the full byte size [] is returned, but it is only half filled with data.

+7
java file file-io byte bytearray
source share
3 answers

You will need to check the return value of RandomAccessFile.read() to determine the number of bytes read. If it differs from chunkSize, you will have to copy the array to a smaller one and return it.

 private byte[] readData(File f, int startByte, int chunkSize) throws Exception { RandomAccessFile raf = new RandomAccessFile(f, "r"); raf.seek(startByte); byte[] data = new byte[chunkSize]; int bytesRead = raf.read(data); if (bytesRead != chunkSize) { byte[] smallerData = new byte[bytesRead]; System.arraycopy(data, 0, smallerData, 0, bytesRead); data = smallerData; } raf.close(); return data; } 
+3
source share

RandomAccessFile.read() returns the number of bytes read, so you can copy the array if necessary:

 private byte[] readData(File f, int startByte, int chunkSize) throws Exception { RandomAccessFile raf = new RandomAccessFile(f, "r"); raf.seek(startByte); byte[] data = new byte[chunkSize]; int read = raf.read(data); raf.close(); if (read == data.length) return data; else return Arrays.copyOf(data, read); } 

If you are using Java pre-6, you need to implement Arrays.copyOf yourself:

 byte[] r = new byte[read]; System.arraycopy(data, 0, r, 0, read); return r; 
+2
source share

You can also use the file size to calculate the remaining number of bytes.

 private byte[] readData(File f, int startByte, int chunkSize) throws Exception { RandomAccessFile raf = new RandomAccessFile(f, "r"); raf.seek(startByte); int size = (int) Math.min(chunkSize, raf.length()-startByte); byte[] data = new byte[size]; raf.read(data); // TODO check the value returned by read (throw Exception or loop) raf.close(); return data; } 

Thus, you do not create an additional array and do not need a copy. Probably not a big influence.
One important point of IMO: check the value returned by read , I think it may be less than the rest of the bytes. Javadoc state:

The number of bytes read is at most equal to the length b

0
source share

All Articles