来自HttpURLConnection的意外结果 - 读取远程二进制文件

时间:2009-03-04 16:28:34

标签: java binary httpurlconnection

我正试图从互联网上读取一个远程二进制文件(比如图像):

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%。因此文件已损坏,无法使用图像查看器正确打开。

我该如何解决这个问题?

1 个答案:

答案 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。