1

好的,我知道这个问题可能很愚蠢,但我以前从未这样做过,所以我问了这个问题。我如何使用 Thread 类下载文件(比如说,从互联网上)?

4

2 回答 2

1

“使用线程类”是什么意思?我猜你想下载一个线程化的文件,这样它就不会阻塞你的用户界面或程序的其他部分。

我假设您使用 C++ 和 WINAPI。首先创建一个线程。本教程提供了有关 WIN32 线程的良好信息。该线程将负责下载文件。为此,您只需连接到端口 80 上的网络服务器并发送 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 响应,其中包含带有前面标头的文件。解析此标头并读取内容。

可以在此处找到有关 HTTP 的更多信息。

于 2012-10-15T10:55:22.160 回答
1

如果建议您不要使用线程下载文件。最好使用更针对 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(); 
}

您可能想详细说明错误处理。简而言之,这段代码的作用是:

有关其工作原理的更详细说明,请参阅代码注释。

于 2012-10-15T11:20:30.777 回答