我正试图从互联网上读取一个远程二进制文件(比如图像):
HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection(); //myUrl - URL object pointing for some location
if(connection.getResponseCode() == 200){
File temp = File.createTempFile("blabla", fileName); //fileName - string name of file
FileOutputStream out = new FileOutputStream(temp);
int fileSize = Integer.parseInt(connection.getHeaderField("content-length"));
int counter = 0;
DataInputStream in = new DataInputStream(connection.getInputStream());
byte ch[] = new byte[1024];
System.out.println(counter);
while((counter += in.read(ch)) > 0){
out.write(ch);
if(counter == fileSize){
out.close();
break;
}
}
}
本地Web服务器(localhost)的本地使用效果非常好。
但是。然后myUrl是某个远程Web服务器上的文件的URL - 它返回意外的结果。例如,从给定文件的来源看来,它似乎重复了一些包(我认为是因为先前的或者某些的腐败),并且由于这种重复,所得到的文件通常比原始文件大10%。因此文件已损坏,无法使用图像查看器正确打开。
我该如何解决这个问题?
答案 0 :(得分:4)
read
不一定会读取整个缓冲区(特别是如果它位于流的末尾)。
所以改变你的循环:
for (;;) {
int len = in.read(ch);
if (len == -1) {
break;
}
out.write(ch, 0, len);
}
也许把代码放在某个方法中。
另请注意:
DataInputStream
没有意义(尽管readFully
通常很有用)。始终使用通常的习语关闭资源(例如流):
final Resource resource = acquire();
try {
use(resource);
} finally {
resource.close();
}
可能没什么区别,但1024的缓冲区大小有点小。我倾向于任意默认为8192。