writzlpfrimpft:
私は、できるだけ少数のサードパーティのライブラリとして使用してWebサーバー(HTTPまたはHTTPS)から単一のファイルをダウンロードしようとしています。
次のように私が作ってみた方法は次のとおりです。
private static final int BUFFER_SIZE = 8;
public static boolean download(URL url, File f) throws IOException {
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
FileOutputStream out = new FileOutputStream(f);
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
byte[] buffer;
long dld = 0, expected = conn.getContentLengthLong(); // TODO expected will be -1 if the content length is unknown
while (true) { // TODO fix endless loop if server timeout
buffer = new byte[BUFFER_SIZE];
int n = in.read(buffer);
if (n == -1) break;
else dld += n;
out.write(buffer);
}
out.close();
System.out.println(dld + "B transmitted to " + f.getAbsolutePath());
return true;
}
意図したとおりしかし、それは決して作業によって行います。私はダウンロードしてみましたhttps://upload.wikimedia.org/wikipedia/commons/6/6d/Rubber_Duck_Florentijn_Hofman_Hong_Kong_2013d.jpgを結果は恐ろしいだった、例えば:
何らかの理由で私はIrfanViewはではなく、他のビューアで画像を表示することができたので、これは再保存されたバージョンです。
私は、バッファサイズまたはダウンロードする他の画像をいじってみましたが、結果は、多かれ少なかれ同じです。
私は、ファイルを見れば、単にドットに置き換えたコンテンツの全体部分があります。
私は本当にすべての助けに感謝しますので、この1に迷ってしまいました:)
ベンジャミン・アーカート:
読むために8バイトのデータが存在しない場合に問題が発生します。あなたがバイナリエディタで非常に多くのを見ている理由であるゼロで埋め配列、この葉の部分。
解決策は単純です:置き換えるout.write(buffer);
とout.write(buffer, 0, n);
。これが唯一のインデックス間のバイト読み取るためのFileOutputStreamを伝える0
とをn
。
固定コード:
private static final int BUFFER_SIZE = 8;
public static boolean download(URL url, File f) throws IOException {
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
FileOutputStream out = new FileOutputStream(f);
BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
// We can move the buffer declaration outside the loop
byte[] buffer = new byte[BUFFER_SIZE];
long dld = 0, expected = conn.getContentLengthLong(); // TODO expected will be -1 if the content length is unknown
while (true) {
int n = in.read(buffer);
if (n == -1) break;
else dld += n;
out.write(buffer, 0, n);
}
out.close();
System.out.println(dld + "B transmitted to " + f.getAbsolutePath());
return true;
}