0

I need to read a file into a byte array in Java. Fortunately, this question has been answered very well, and I am able to use the nio libraries from Java 7.

Here's the twist though: The resulting byte array needs to have a size which is a multiple of 8. The extra bytes should be null, i.e. \0.

Is there a quick and readable way to pad the byte array with zeros so that its size is a multiple of 8? Note that readability and speed of development is key here - if the best solution adds more than a few lines in addition simply reading the file into a byte array, I'd rather simply copy the entire buffer into a new array.

Edit:

A bit more reading suggests that I can modify this answer and simply round the size of the buffer to the next 8. Any thoughts on the safety and/or effectiveness of this strategy? I believe the bytes in the buffer beyond the end of the file will be initialized to zero and unaffected by the read - is that correct?

Community
  • 1
  • 1

1 Answers1

2

Since 8 is a power of 2, you have a quick way to obtain the next number:

int theSize = (orig + 7) & ~7;

As to reading into a byte array directly, you say you use nio; therefore allocate a ByteBuffer of the requested size and .read() into it from the channel associated with the file (use FileChannel.open()). Then get the underlying array using the .array() method of ByteBuffer. (note: DO NOT .allocateDirect()! Otherwise .array() won't work)

It would have been ideal if you could FileChannel.map() to the wanted size, unfortunately mapping to a greater size modifies the underlying file, so no dice here...


Sample code:

final Path path = Paths.get("path/to/wanted/file");

try (
    final FileChannel channel = FileChannel.open(path, StandardOpenOption.READ);
) {
    final int bufsize = ((int) channel.size() + 7) & ~7;
    final ByteBuffer buf = ByteBuffer.allocate(bufsize);
    channel.read(buf);
    return buf.array();
}
fge
  • 119,121
  • 33
  • 254
  • 329
  • Nifty way of rounding to the nearest 8. I will probably use the method in the second answer I linked to, and use your formula for computing the next index. – Isaac Supeene Dec 01 '14 at 00:40
  • Based on the `ReadableByteChannel` interface, I don't think this is guaranteed to read the whole file in one go. Of course, the answer I linked to also has this problem, but at least the `RandomAccessFile` has a `readFully` method I can use instead. How would you address this issue when using `FileChannel`? – Isaac Supeene Dec 01 '14 at 00:46
  • Hmm, using this method it never failed to read the whole file for me... The doc is kind of unclear indeed, but then a simple loop will fix that: `do { channel.read(buf); } while (buf.position() < channel.size());` – fge Dec 01 '14 at 06:03