私は学校のプロジェクトに取り組んでおり、Webからファイルをダウンロードするために使用できるツールを実装しています(調整オプション付き)。問題は、GUIを用意することです。JProgressBar
ウィジェットを使用して、ダウンロードの現在の進行状況を表示します。そのため、ファイルのサイズを知る必要があります。ファイルをダウンロードする前に、ファイルのサイズをどのように取得しますか。
HTTP応答はすべてContent-Lengthヘッダーを含むと想定されているため、この値をURLConnectionオブジェクトに照会できます。
//once the connection has been opened
List values = urlConnection.getHeaderFields().get("content-Length")
if (values != null && !values.isEmpty()) {
// getHeaderFields() returns a Map with key=(String) header
// name, value = List of String values for that header field.
// just use the first value here.
String sLength = (String) values.get(0);
if (sLength != null) {
//parse the length into an integer...
...
}
サーバーが正確なContent-Lengthを返すことが常に可能であるとは限らないため、値が不正確になる可能性がありますが、少なくとも、ほとんどの場合、some使用可能な値を取得します。
update:または、URLConnection javadocをより完全に確認したので、 getContentLength() メソッドを使用できます。
言及したように、URLConnectionの getContentLengthLong()
が最善の策ですが、常に一定の長さが得られるとは限りません。これは、HTTPプロトコル(およびURLConnection
で表すことができる他のプロトコル)が常に長さを伝えるとは限らないためです。
HTTPの場合、通常、動的コンテンツの長さは事前にわかりません。通常、_content-length
_ヘッダーが送信されるときです。代わりに、別のヘッダー_transfer-encoding
_は、「チャンク」エンコーディングが使用されることを指定します。チャンクエンコーディングでは、応答全体の長さが指定されておらず、応答は分割して送信されます。各分割のサイズが指定されています。実際には、サーバーはサーブレットからの出力をバッファーに入れます。バッファがいっぱいになるたびに、別のチャンクが送信されます。このメカニズムを使用すると、HTTPは実際には無限長の応答のストリーミングを開始できます。
ファイルが2 GBより大きい場合、そのサイズはint
として表すことができないため、古いメソッド getContentLength()
は-1を返します場合。
HEADリクエストを使用して、それ以外の場合は空であった正しいcontent-lengthフィールドを使用してWebサーバーに応答させました。これが一般的に機能するかどうかはわかりませんが、私の場合は機能します:
private int tryGetFileSize(URL url) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
conn.getInputStream();
return conn.getContentLength();
} catch (IOException e) {
return -1;
} finally {
conn.disconnect();
}
}
コンテンツの長さ(URLConnection.getContentLength())を使用する必要があります。残念ながら、これは常に正確であるとは限らず、常に提供されるとは限らないため、これに依存することが常に安全であるとは限りません。
//URLConnection connection
private int FileSize(String url) {
// this is the method and it get the url as a parameter.
// this Java class will allow us to get the size of the file.
URLConnection con;
// its in a try and catch incase the url given is wrong or invalid
try{
// we open the stream
con = new URL(url).openConnection()
return con.getContentLength();
}catch (Exception e){
e.printStackTrace();
// this is returned if the connection went invalid or failed.
return 0;
}
}
@ericksonが言ったように、「Content-Length:」の代わりに「Transfer-Encoding:chunked」というヘッダーがある場合があり、もちろん長さにnull値があります。
Available()メソッドについて-適切な値が返されることを誰も保証できないため、使用しないことをお勧めします。