HttpURLConnectionからの予期しない結果-リモートバイナリファイルの読み取り
-
03-07-2019 - |
質問
次のようにインターネットからリモートバイナリファイル(画像など)を読み取ろうとしています:
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に設定する傾向があります。
所属していません StackOverflow