Java - download file over network using buffer

I want to read from a network stream and write bytes to a file directly. But every time I run the program, very few bytes are actually written to the file.

Java:

InputStream in = uc.getInputStream();
int clength=uc.getContentLength();
byte[] barr = new byte[clength];
int offset=0;
int totalwritten=0;
int i;
int wrote=0;

OutputStream out = new FileOutputStream("file.xlsx");
while(in.available()!=0) { 
   wrote=in.read(barr, offset, clength-offset);
   out.write(barr, offset, wrote);
   offset+=wrote;
   totalwritten+=wrote;
}
System.out.println("Written: "+totalwritten+" of "+clength);
out.flush();

      

+3


source to share


2 answers


This is because available () doesn't do what you think it does. Read its API documentation. You should just read as long as the number of bytes read returned read()

is -1. Or even simpler, use Files.copy()

:

Files.copy(in, new File("file.xlsx").toPath());

      

Using a buffer that is the size of the input stream also greatly violates the purpose of using a buffer that should only have a few bytes in memory.



If you want to override copy()

, the general pattern is as follows:

byte[] buffer = new byte[4096]; // number of bytes in memory
int numberOfBytesRead;
while ((numberOfBytesRead = in.read(buffer)) >= 0) {
    out.write(buffer, 0, numberOfBytesRead);
}

      

+3


source


You are using .available () wrong. From Java Documentation :

available () returns an estimate of the number of bytes that can be read (or skipped) from this input stream without blocking by the next method call on this input stream



This means that the first time your stream is slower than the file's write speed (very soon, in all likelihood), time runs out.

You should either prepare a thread waiting for input until it reads the entire expected length of the content (with a long latency, of course), or just block your program waiting if user interaction is not a big problem.

0


source







All Articles