Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HttpURLConnection产生意外结果-读取远程二进制文件_Java_Binary_Httpurlconnection - Fatal编程技术网

Java HttpURLConnection产生意外结果-读取远程二进制文件

Java HttpURLConnection产生意外结果-读取远程二进制文件,java,binary,httpurlconnection,Java,Binary,Httpurlconnection,我正试图从internet上读取远程二进制文件(例如,图像),如下所示: HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection(); //myUrl - URL object pointing for some location if(connection.getResponseCode() == 200){ File temp = File.createTempFile("blabla", fil

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

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


如何解决这个问题?

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


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


为了完成,大多数Java程序员更喜欢较短的变体:int-len;虽然((len=in.read(ch))>=0){out.write(ch,0,len);}保存了一个条件,但中断并重用堆栈上的变量,这使得它不太容易出错。a希望避免副作用。重用变量不是最佳实践!作为补充,大多数Java程序员更喜欢较短的变体:int-len;虽然((len=in.read(ch))>=0){out.write(ch,0,len);}保存了一个条件,但中断并重用堆栈上的变量,这使得它不太容易出错。a希望避免副作用。重用变量不是最佳实践!