HttpURLConnection 出现意外结果 - 读取远程二进制文件

发布于 2024-07-14 16:37:53 字数 993 浏览 7 评论 0原文

我正在尝试从互联网上读取远程二进制文件(例如图像),如下所示:

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;
        }
    }
}

在本地使用本地网络服务器(本地主机),它工作得很好。

但。 然后 myUrl 是某个远程 Web 服务器上文件的 URL - 它返回意外结果。 例如,从给定文件的来源来看,它似乎重复了一些包(我认为是因为以前的包或某些包被损坏),并且由于这种重复,生成的文件通常比原始文件大 10% 左右。 因此文件已损坏,无法使用图像查看器正确打开。

我该如何解决这个问题?

I'm trying to read a remote binary file (say, image) from internet like this:

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;
        }
    }
}

Locally of with local web server (localhost) it works perfectly.

But. Then myUrl is URL of file on some remote web server - it returns unexpected results. For instance, from sources of given files it seems that it repeats some packages (I think because of corruption of previous ones or someting) and the resulting file usually is about 10% bigger than original one because of this repeats. So file is corrupted and cannot be opened correctly with image viewers.

How can I solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残花月 2024-07-21 16:37:53

read 不一定读取整个缓冲区(特别是如果它位于流的末尾)。

因此,改变你的循环:

for (;;) {
    int len = in.read(ch);
    if (len == -1) {
        break;
    }
    out.write(ch, 0, len);
}

也许将该代码放在某个方法中。

另请注意:

  • 此处使用 DataInputStream 没有意义(尽管 readFully 通常很有用)。
  • 始终使用通常的习惯用法关闭资源(例如流):

    最终资源资源 = acquire(); 
      尝试 { 
          使用(资源); 
      } 最后 { 
          资源.close(); 
      } 
      
  • 可能不会有太大区别,但 1024 的缓冲区大小有点小。 我倾向于任意默认为 8192。

read does not necessarily read the entire buffer (particularly if it is at the end of the stream).

So change your loop:

for (;;) {
    int len = in.read(ch);
    if (len == -1) {
        break;
    }
    out.write(ch, 0, len);
}

Perhaps put that code in a method somewhere.

Also note:

  • There is no point in using DataInputStream here (although readFully is often useful).
  • Always close resource (such as streams) with the usual idiom:

    final Resource resource = acquire();
    try {
        use(resource);
    } finally {
        resource.close();
    }
    
  • Probably won't make much difference, but a buffer size of 1024 is a bit small. I tend to default to 8192 arbitrarily.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文