我想从网络流中读取并直接将字节写入文件。 但是每次运行程序时,实际上只有很少的字节写入文件。
爪哇:
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();
答案 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()返回可读取的字节数的估计值 (或跳过)来自此输入流而不会被下一个阻塞 调用此输入流的方法
这意味着你的流第一次比你的文件写入速度慢(很快就会很快),但是结束了。
如果用户交互不是什么大问题,你应该准备一个等待输入的线程,直到它读取了所有预期的内容长度(当然有一个相当大的超时),或者只是在等待中阻止你的程序。