わかりました、非常にばかげた質問かもしれませんが、今までやったことがなかったので、この質問をします。Threadクラスを使用してファイルを(たとえば、インターネットから)ダウンロードするにはどうすればよいですか?
2 に答える
「スレッドクラスを使用する」とはどういう意味ですか? UIやプログラムの他の部分をブロックしないように、スレッド化されたファイルをダウンロードしたいと思います。
C++ と WINAPI を使用していると仮定します。まずスレッドを作成します。このチュートリアルは、WIN32 スレッドに関する優れた情報を提供します。このスレッドは、ファイルのダウンロードを担当します。これを行うには、ポート 80 で Web サーバーに接続し、必要なファイルの HTTP GET 要求を送信するだけです。これは次のようになります (改行文字に注意してください)。
GET /path/to/your/file.jpg HTTP/1.1\r\n
Host: www.host.com\r\n
Connection: close\r\n
\r\n
\r\n
サーバーは、ヘッダーが前にあるファイルを含む HTTP 応答で応答します。このヘッダーを解析して内容を読み取ります。
ファイルのダウンロードにスレッドを使用しないことをお勧めします。スレッドよりもオーバーヘッドが少ないため、より I/O を対象とした非同期構造を使用することをお勧めします。使用している .NET Framework のバージョンはわかりませんが、4.5 では次のように動作するはずです。
private static Task DownloadFileAsync(string uri, string localPath)
{
// Get the http request
HttpWebRequest webRequest = WebRequest.CreateHttp(uri);
// Get the http response asynchronously
return webRequest.GetResponseAsync()
.ContinueWith(task =>
{
// When the GetResponseAsync task is finished, we will come
// into this contiuation (which is an anonymous method).
// Check if the GetResponseAsync task failed.
if (task.IsFaulted)
{
Console.WriteLine(task.Exception);
return null;
}
// Get the web response.
WebResponse response = task.Result;
// Open a file stream for the local file.
FileStream localStream = File.OpenWrite(localPath);
// Copy the contents from the response stream to the
// local file stream asynchronously.
return response.GetResponseStream().CopyToAsync(localStream)
.ContinueWith(streamTask =>
{
// When the CopyToAsync task is finished, we come
// to this continuation (which is also an anonymous
// method).
// Flush and dispose the local file stream. There
// is a FlushAsync method that will flush
// asychronously, returning yet another task, but
// for the sake of brevity I use the synchronous
// method here.
localStream.Flush();
localStream.Dispose();
// Don't forget to check if the previous task
// failed or not.
// All Task exceptions must be observed.
if (streamTask.IsFaulted)
{
Console.WriteLine(streamTask.Exception);
}
});
// since we end up with a task returning a task we should
// call Unwrap to return a single task representing the
// entire operation
}).Unwrap();
}
エラー処理について少し詳しく説明します。このコードが行うことは、要するに次のとおりです。
それがどのように機能するかのより詳細な説明については、コードのコメントを参照してください。