httpヘッダーからファイルサイズを取得する方法
-
02-07-2019 - |
質問
http://.../ ファイルをダウンロードする前に、ファイルのサイズを取得したいと考えています。ファイルは、Web ページ、画像、またはメディア ファイルです。これはHTTPヘッダーを使用して実行できますか?ファイルの HTTP ヘッダーだけをダウンロードするにはどうすればよいですか?
解決
はい、通信している HTTP サーバーがこれをサポート/許可していると仮定します。
public long GetFileSize(string url)
{
long result = -1;
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
req.Method = "HEAD";
using (System.Net.WebResponse resp = req.GetResponse())
{
if (long.TryParse(resp.Headers.Get("Content-Length"), out long ContentLength))
{
result = ContentLength;
}
}
return result;
}
HEAD メソッドの使用が許可されていない場合、またはサーバー応答に Content-Length ヘッダーが存在しない場合、サーバー上のコンテンツのサイズを確認する唯一の方法は、コンテンツをダウンロードすることです。これは特に信頼できるものではないため、ほとんどのサーバーにはこの情報が含まれています。
他のヒント
これはHTTPヘッダーを使用して実行できますか?
はい、これが進むべき道です。 もし 情報が提供されると、ヘッダーに Content-Length
. 。ただし、必ずしもそうとは限らないことに注意してください。
ヘッダーのみのダウンロードは、 HEAD
の代わりにリクエストする GET
. 。おそらく次のコードが役立つでしょう。
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://example.com/");
req.Method = "HEAD";
long len;
using(HttpWebResponse resp = (HttpWebResponse)(req.GetResponse()))
{
len = resp.ContentLength;
}
のコンテンツの長さのプロパティに注目してください。 HttpWebResponse
オブジェクト – 解析する必要はありません Content-Length
手動でヘッダーを付けます。
WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));
すべてのサーバーが受け入れられるわけではないことに注意してください HTTP HEAD
リクエスト。ファイル サイズを取得する別のアプローチの 1 つは、 HTTP GET
ファイルの一部のみを要求するサーバーを呼び出して応答を小さくし、応答コンテンツ ヘッダーの一部として返されるメタデータからファイル サイズを取得します。
標準 System.Net.Http.HttpClient
これを達成するために使用できます。部分的なコンテンツは、要求メッセージ ヘッダーのバイト範囲を次のように設定することによって要求されます。
request.Headers.Range = new RangeHeaderValue(startByte, endByte)
サーバーは、要求された範囲とファイル全体のサイズを含むメッセージで応答します。この情報は、応答コンテンツ ヘッダー (response.Content.Header
)「Content-Range」キーを使用します。
応答メッセージのコンテンツ ヘッダーのコンテンツ範囲の例を次に示します。
{
"Key": "Content-Range",
"Value": [
"bytes 0-15/2328372"
]
}
この例では、ヘッダー値は、応答にバイト 0 ~ 15 (つまり、合計 16 バイト) が含まれており、ファイル全体が 2,328,372 バイトであることを示しています。
このメソッドの実装例を次に示します。
public static class HttpClientExtensions
{
public static async Task<long> GetContentSizeAsync(this System.Net.Http.HttpClient client, string url)
{
using (var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url))
{
// In order to keep the response as small as possible, set the requested byte range to [0,0] (i.e., only the first byte)
request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(from: 0, to: 0);
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
if (response.StatusCode != System.Net.HttpStatusCode.PartialContent)
throw new System.Net.WebException($"expected partial content response ({System.Net.HttpStatusCode.PartialContent}), instead received: {response.StatusCode}");
var contentRange = response.Content.Headers.GetValues(@"Content-Range").Single();
var lengthString = System.Text.RegularExpressions.Regex.Match(contentRange, @"(?<=^bytes\s[0-9]+\-[0-9]+/)[0-9]+$").Value;
return long.Parse(lengthString);
}
}
}
}