C#で、指定されたURLに接続し、そのコンテンツのサイズがゼロかどうかを確認するメソッドをご紹介します。
はじめに
HTTPレスポンスにContent-Lengthヘッダーが設定されていない場合に、接続先にあるコンテンツが空ではないかチェックしたかったので、本メソッドを作成しました。
ソースコード
以下がソースコードになります。
引数で渡されたURLにGETリクエストを送信し、ストリームとしてレスポンスを取得しています。
取得出来なかった場合はサイズがゼロとして、trueを返してします。
class Program
{
static void Main(string[] args)
{
string url = "";
try
{
if (IsContentSizeZero(url).Result)
{
Console.WriteLine("コンテンツなし");
}
else
{
Console.WriteLine("コンテンツあり");
}
}
catch(Exception ex){
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 指定された URL のコンテンツサイズがゼロかどうかを確認します。
/// </summary>
/// <param name="url">コンテンツサイズをチェックしたい URL</param>
/// <returns>コンテンツのサイズがゼロの場合は <c>true</c>、そうでない場合は <c>false</c></returns>
/// <exception cref="HttpRequestException">HTTPリクエストの処理中にエラーが発生した場合にスローされます。</exception>
/// <exception cref="ArgumentNullException">URL が null または空の場合にスローされます。</exception>
public static async Task<bool> IsContentSizeZero(string url)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException(nameof(url), "URLが空またはnullです。");
}
using HttpClient client = new();
try
{
// GETリクエストを送信してレスポンスを取得
HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
// ストリームとしてレスポンスの内容を取得
using Stream stream = await response.Content.ReadAsStreamAsync();
byte[] buffer = new byte[8192];
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
// サイズが0の場合はtrueを返す
return bytesRead == 0;
}
catch (HttpRequestException ex)
{
Console.WriteLine("HTTPリクエストの処理中にエラーが発生しました。" + ex.Message);
return false;
}
catch (Exception ex)
{
Console.WriteLine("予期せぬエラーが発生しました。" + ex.Message);
return false;
}
}
}コードのポイントです。
HttpClient と HttpCompletionOption.ResponseHeadersRead を使うことで、レスポンス全体ではなくヘッダ取得時点で読み込みを開始しています。
実際にレスポンスストリームを読み込み、ReadAsync で最初のバイトを読み取ることにより、コンテンツの有無を簡易的にチェックしています。
エラーハンドリングを実装しており、ネットワークエラーや空文字URLなどにも対応可能です。
改善点
URLによってはリダイレクトや403・404などが発生するため、ステータスコードのチェックを追加してもいいかもしれません。
HTMLなどの軽いレスポンスではコンテンツサイズが小さい場合もあるので、用途によってはバイト数ではなくステータスやヘッダーによるチェックがいい場合もあります。
リンク



コメント