Look at Channels.newChannel(OutputStream). It will give you a channel given an OutputStream. With the WritableByteChannel adapter you can provide the ByteBuffer which will write it to the OutputStream.
public void writeBuffer(ByteBuffer buffer, OutputStream stream) {
WritableByteChannel channel = Channels.newChannel(stream);
channel.write(buffer);
}
This should do the trick!
Answer from ng. on Stack OverflowVideos
Use Apache Commons IO
FileUtils.writeByteArrayToFile(new File("pathname"), myByteArray)
Or, if you insist on making work for yourself...
try (FileOutputStream fos = new FileOutputStream("pathname")) {
fos.write(myByteArray);
//fos.close(); There is no more need for this line since you had created the instance of "fos" inside the try. And this will automatically close the OutputStream
}
Without any libraries:
try (FileOutputStream stream = new FileOutputStream(path)) {
stream.write(bytes);
}
With Google Guava:
Files.write(bytes, new File(path));
With Apache Commons:
FileUtils.writeByteArrayToFile(new File(path), bytes);
All of these strategies require that you catch an IOException at some point too.
For me the best in this case is Apache commons-io to handle this and similar tasks.
The IOUtils type has a static method to read an InputStream and return a byte[].
InputStream is;
byte[] bytes = IOUtils.toByteArray(is);
Internally this creates a ByteArrayOutputStream and copies the bytes to the output, then calls toByteArray().
UPDATE: as long as you have the byte array, as @Peter pointed, you have to convert to ByteBuffer
ByteBuffer.wrap(bytes)
JAVA 9 UPDATE: as stated by @saka1029 if you're using java 9+ you can use the default InputStream API which now includes InputStream::readAllBytes function, so no external libraries needed
InputStream is;
byte[] bytes = is.readAllBytes()
What is about:
ReadableByteChannel channel = Channels.newChannel(inputStream);
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
while (channel.read(buffer) != -1) {
//write buffer
};
The reason why your file when written using the ByteBuffer is bigger is because of how you initialize the ByteBuffer. When you simply write using writeInt(int), you are writing only the data that you need to write. However, when you create your ByteBuffer, you create it larger than it needs to be to prevent overflow which I understand. However, that also means that the underlying array, the one returned from the array() method, is also larger than it needs to be. Since arrays don't understand positions and limits, when you write the array, all of the data and the empty space after that is written, causing the large file size. What you need to do is after putting all of your data inside the buffer, you need to flip the buffer and then create a new array with length the same as the limit() of the buffer (once flipped), and then get(byte[]) all of the data from the buffer. Once you have that array, you need to write it.
This is what I'm talking about:
try (RandomAccessFile out = new RandomAccessFile(file, "rw")) {
ByteBuffer buffer = ByteBuffer.allocate(totalPkts*4);
for(int i = 0; i < totalPkts; i++) {
buffer.putInt(data.get(i));
}
buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
out.write(data);
}
If you would like to reduce the amount of writes consider using a byte array to write to a file stream. (provided the data in data variable can be converted to bytes). As for not being the same please check if you are flushing the stream at some point and closing it properly before program termination.