There is such a method that helps me convert my files to byte[]

 private byte[] getBytes(File zipToSend) { byte[] buffer = new byte[(int) zipToSend.length()]; BufferedInputStream bos = null; try { bos = new BufferedInputStream(new FileInputStream(zipToSend)); bos.read(buffer); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } } return buffer; } 

There are 2 questions:

  1. But as far as I know the read(buffer); method read(buffer); it may not read all the bytes in the buffer ... Thus, I risk losing part of the bytes.
  2. Do I dare to get OOM if I specify byte[] buffer = new byte[(int) zipToSend.length()]; ? After all, the buffer size depends on the size of the file being transferred, and if this is a folder of 50+ MB in size ...

Here I wrote the second alternative method

 private byte[] getBytes(File zipToSend) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); BufferedInputStream bos = null; byte[] buffer = new byte[16384]; int count; try { bos = new BufferedInputStream(new FileInputStream(zipToSend)); while ((count = bos.read(buffer, 0, buffer.length)) != -1) { baos.write(buffer, 0, count); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } } return baos.toByteArray(); } 

In this example, I exclude the possibility of losing bytes and getting OOM, but in this case the execution time is increased 10 times ...

But all the same for us, of course, it is more important to get a full amount of data.

Are my beliefs about the first example correct?

  • one
    You understand that if you use ByteArrayOutputStream , it still uses the buffer, and not the fact that it is no more than a simple array. At the same time, it allocates a small buffer, and then increases it as you add bytes, which means creating a new buffer, copying all values ​​into it, which takes more time. In the first method, everything is fine, but the byte array will weigh as much as the file. The file is fully respected, unless there is a physical disconnection of the carrier, or the system decides to forbid you to read it - selya
  • one
    I think in your case (and in general) the second version of the implementation, of course, is correct. But an error may occur during the reading anyway, if I am not mistaken. You can try to start reading the file, and under the debug, having read the part, physically delete the file and see what happens. Most likely, IOException will IOException and you will not return the entire array - Chubatiy

1 answer 1

Neither the first nor the second method excludes neither the OOM, nor the possibility of the return of an unread file, in the case of some kind of exempt in the process of reading the file (although this is usually unlikely). To not get OOM - do not read the file completely in memory. To be sure that the entire file is read - do not turn off the exceptions in the try / catch blocks and forward them to the top, then if there was any error in the reading process, you will receive not some half-filled byte array, but an answer that, in my opinion it is better.

  • How about OOM, how likely is it to get it? Is it possible with file size up to 50 mb? Or should the file be very large? - Aleksey Timoshchenko
  • It all depends on the size of the heap (heap space) that you installed when you started your application (the -Xmx option). If my memory serves me, then on most JVMs, the default is about 64 MB. Here is a link to an English-language article on the topic: plumbr.eu/outofmemoryerror/java-heap-space - Sergi