我正在尝试下载多个文件,但它并没有像我希望的那样工作。 有人可以告诉我这个剧本有什么问题,因为我已经尝试了很多东西而且真的不知道该怎么做了。
public static void DownloadFile(string url)
{
WebClient client = new WebClient();
var name = url.Substring(url.LastIndexOf('/')).Remove(0, 1);
foreach (var item in urls)
{
client.DownloadFile(item, "C:\\" + name);
}
}
private void btnGo_Click(object sender, EventArgs e)
{
urls.Add("url1");
urls.Add("url2");
urls.Add("url3");
Parallel.ForEach(urls,
new ParallelOptions { MaxDegreeOfParallelism = 10 },
DownloadFile);
}
using (var sr = new StreamReader(HttpWebRequest.Create(url).GetResponse().GetResponseStream()))
{
using (var sw = new StreamWriter(url.Substring(url.LastIndexOf('/'))))
{
sw.Write(sr.ReadToEnd());
}
}
答案 0 :(得分:5)
我会改用System.Net.HttpWebRequest
。
这就是代码的样子:
private List<string> urls = new List<string>();
private void btnGo_Click(object sender, EventArgs e)
{
urls.Add("http://199.91.152.106/ua0p3fbc5nlg/gg2w2fq4ljc1nnd/MicroCraft_Beta.zip");
Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile);
}
public static void DownloadFile(string url)
{
var req = (HttpWebRequest)WebRequest.Create(url);
var name = url.Substring(url.LastIndexOf('/') + 1);
using (var res = (HttpWebResponse)req.GetResponse())
using (var resStream = res.GetResponseStream())
using (var fs = new FileStream("C:\\" + name, FileMode.Create, FileAccess.Write, FileShare.None))
{
// Save to file
var buffer = new byte[8 * 1024]; // 8 KB buffer
int len; // Read count
while ((len = resStream.Read(buffer, 0, buffer.Length)) > 0)
fs.Write(buffer, 0, buffer.Length);
}
}
因为您在评论中告诉我的URL没有使用HTTP协议的正确实现。您必须将它添加到您的配置文件才能使其工作(App.config或Web.config,具体取决于它是ASP.Net站点还是离线应用程序):
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
关于您在评论中提到的名称冲突问题,应该通过将var name = url.Substring(url.LastIndexOf('/')).Remove(0, 1);
更改为其他内容来解决此问题。
如果您想拥有增量文件名,可以使用:
// Inside your class:
private static int counter = 0;
// In your method:
var name = "file" + System.Threading.Interlocked.Increment(ref counter) + ".html";
答案 1 :(得分:1)
您正在将所有文件下载到DownloadFile代码中的同一文件,该代码假定单个调用此函数会下载所有文件。
修正:
选项1:不要使用Parallel.ForEach
,只需调用一次DownloadFile即可。为每次下载指定唯一的文件名。即通过参与您正在下载的Url或仅使用随机/临时文件名。
这样的事情(假设网址是某种IEnumerable<string>
)
foreach (var item in urls)
{
var name = item.Substring(item.LastIndexOf('/')).Remove(0, 1);
client.DownloadFile(item, "C:\\" + name);
}
选项2:使用Parallel.ForEach
但更改DownloadFile代码以仅下载单个文件:
public static void DownloadFile(string url)
{
WebClient client = new WebClient();
var name = url.Substring(url.LastIndexOf('/')).Remove(0, 1);
client.DownloadFile(url, "C:\\" + name);
}