私は学校向けのプロジェクトに取り組んでおり、Webからファイルをダウンロードするために使用できるツールを実装しています(スロットルオプション付き)。つまり、GUIを用意し、JProgressBar
ウィジェットを使用して、ダウンロードの現在の進行状況を表示します。そのためには、ファイルのサイズを知る必要があります。ファイルをダウンロードする前に、どのようにしてファイルのサイズを取得しますか。
6 に答える
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 を返すことができるとは限らないため、値が不正確になる可能性がありますが、少なくともほとんどの場合、使用可能な値が得られます。
更新:または、URLConnection javadoc をより完全に見たので、getContentLength()メソッドを使用することもできます。
前述のように、URLConnectiongetContentLengthLong()
が最善の策ですが、常に明確な長さが得られるとは限りません。これは、HTTP プロトコル (および で表すことができる他のものURLConnection
) が常に長さを伝えるとは限らないためです。
HTTP の場合、動的コンテンツの長さは、通常、content-length
ヘッダーが通常送信されるときに事前にわかりません。代わりに、別のヘッダー でtransfer-encoding
、「チャンクされた」エンコーディングが使用されることを指定します。チャンク エンコーディングでは、応答全体の長さは指定されておらず、応答は分割されて返され、各部分のサイズが指定されます。実際には、サーバーはサーブレットからの出力をバッファリングします。バッファがいっぱいになるたびに、別のチャンクが送信されます。このメカニズムを使用すると、HTTP は実際に無限の長さの応答のストリーミングを開始できます。
ファイルが 2 Gb より大きい場合、そのサイズは として表すことができないint
ため、その場合、古いメソッドはgetContentLength()
-1 を返します。
HEAD リクエストを使用して、Web サーバーに正しい content-length フィールドを返信させましたが、それ以外の場合は空でした。これが一般的に機能するかどうかはわかりませんが、私の場合は機能します:
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() メソッドについて - 適切な値が返されるとは誰も保証できないため、使用しないことをお勧めします。