Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How to "trim" a byte array?

So I have some code that reads a certain amount of bytes from a file and returns the resulting byte array (this is basically used for chunking up files to send over the network as (eventually) base64-encoded ascii text).

It works fine, except that when the last chunk of the file is generated, it isnt a full chunk. Therefore, the resulting byte array isnt full. However, it is a constant size, which means that the file is reassembled there is a whole bunch of extra data (0's maybe) appended to the end.

How can I make it so that the byte[] for the last chunk of the file really only contains the data it needs to? The code looks like this:

 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 bigger than the remaining bytes in the file, a full sized byte[] gets returned but its only half-full with data.

like image 939
Erin Drummond Avatar asked Dec 17 '09 02:12

Erin Drummond


2 Answers

You'll have to check the return value of RandomAccessFile.read() to determine the number of bytes read. If it's different than the chunkSize, you'll have to copy the array over to a smaller one and return that.

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;
}
like image 157
Asaph Avatar answered Oct 03 '22 10:10

Asaph


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

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, then you need to implement Arrays.copyOf yourself:

byte[] r = new byte[read];
System.arraycopy(data, 0, r, 0, read);
return r;
like image 42
notnoop Avatar answered Oct 03 '22 10:10

notnoop