Java - 使用缓冲区通过网络下载文件

时间:2014-12-30 14:30:01

标签: java network-programming

我想从网络流中读取并直接将字节写入文件。 但是每次运行程序时,实际上只有很少的字节写入文件。

爪哇:

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();

2 个答案:

答案 0 :(得分:3)

那是因为available()没有按照你的想法做到。阅读其API文档。您应该只读取,直到read()返回的读取字节数为-1。或者甚至更简单,使用Files.copy()

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

使用具有输入流大小的缓冲区也几乎违背了使用缓冲区的目的,即在内存中只有几个字节。

如果您想重新实现copy(),一般模式如下:

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

答案 1 :(得分:0)

您正在使用.available()错误。来自Java documentation

  

available()返回可读取的字节数的估计值   (或跳过)来自此输入流而不会被下一个阻塞   调用此输入流的方法

这意味着你的流第一次比你的文件写入速度慢(很快就会很快),但是结束了。

如果用户交互不是什么大问题,你应该准备一个等待输入的线程,直到它读取了所有预期的内容长度(当然有一个相当大的超时),或者只是在等待中阻止你的程序。

相关问题