WebClient 没有从提供的 URL 下载正确的文件
WebClient isn't downloading the right file from the supplied URL
我想从 Linux 发行版下载 .torrent 文件,但出于某种原因,从我的应用程序下载的最终文件与手动下载的文件不同。我的应用程序下载的那个有 31KB,它是一个无效的 .torrent 文件,而右边的一个(当我手动下载时)有 41KB,它是有效的。
我要下载的文件中的 URL 是 http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent
为什么会这样,我怎样才能下载同一个文件(有效文件,41KB)?
谢谢。
上述下载文件方法的C#代码:
string sLinkTorCache = @"http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent";
using (System.Net.WebClient wc = new System.Net.WebClient())
{
var path = @"D:\Baixar automaticamente"; // HACK Pegar isso dos settings na versão final
var data = Helper.Retry(() => wc.DownloadData(sLinkTorCache), TimeSpan.FromSeconds(3), 5);
string fileName = null;
// Try to extract the filename from the Content-Disposition header
if (!string.IsNullOrEmpty(wc.ResponseHeaders["Content-Disposition"]))
{
fileName = wc.ResponseHeaders["Content-Disposition"].Substring(wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 10).Replace("\"", "");
}
var torrentPath = Path.Combine(path, fileName ?? "Arch Linux Distro");
if (File.Exists(torrentPath))
{
File.Delete(torrentPath);
}
Helper.Retry(() => wc.DownloadFile(new Uri(sLinkTorCache), torrentPath), TimeSpan.FromSeconds(3), 5);
}
Helper.Retry(出现HTTP异常时重试):
public static void Retry(Action action, TimeSpan retryInterval, int retryCount = 3)
{
Retry<object>(() =>
{
action();
return null;
}, retryInterval, retryCount);
}
public static T Retry<T>(Func<T> action, TimeSpan retryInterval, int retryCount = 3)
{
var exceptions = new List<Exception>();
for (int retry = 0; retry < retryCount; retry++)
{
try
{
if (retry > 0)
System.Threading.Thread.Sleep(retryInterval); // TODO adicionar o Using pro thread
return action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
我最初虽然网站认为这是来自机器人的请求(也就是说,它正在检查一些 headers),但它正在响应垃圾邮件。在查看 Fiddler 之后 - 看起来返回的数据对于网络浏览器和代码来说是完全相同的。这意味着,我们没有正确缩小(提取)响应。 Web 服务器压缩数据(使用类似 gzip 的东西)是很常见的。 WebClient
不会 自动缩减数据。
使用 Automatically decompress gzip response via WebClient.DownloadData 的答案 - 我设法让它正常工作。
另请注意,您正在下载该文件两次。你不需要那样做。
工作代码:
//Taken from above linked question
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
并使用它:
string sLinkTorCache = @"http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent";
using (var wc = new MyWebClient())
{
var path = @"C:\Junk";
var data = Helper.Retry(() => wc.DownloadData(sLinkTorCache), TimeSpan.FromSeconds(3), 5);
string fileName = "";
var torrentPath = Path.Combine(path, fileName ?? "Arch Linux Distro.torrent");
if (File.Exists(torrentPath))
File.Delete(torrentPath);
File.WriteAllBytes(torrentPath, data);
}
我想从 Linux 发行版下载 .torrent 文件,但出于某种原因,从我的应用程序下载的最终文件与手动下载的文件不同。我的应用程序下载的那个有 31KB,它是一个无效的 .torrent 文件,而右边的一个(当我手动下载时)有 41KB,它是有效的。
我要下载的文件中的 URL 是 http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent
为什么会这样,我怎样才能下载同一个文件(有效文件,41KB)?
谢谢。
上述下载文件方法的C#代码:
string sLinkTorCache = @"http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent";
using (System.Net.WebClient wc = new System.Net.WebClient())
{
var path = @"D:\Baixar automaticamente"; // HACK Pegar isso dos settings na versão final
var data = Helper.Retry(() => wc.DownloadData(sLinkTorCache), TimeSpan.FromSeconds(3), 5);
string fileName = null;
// Try to extract the filename from the Content-Disposition header
if (!string.IsNullOrEmpty(wc.ResponseHeaders["Content-Disposition"]))
{
fileName = wc.ResponseHeaders["Content-Disposition"].Substring(wc.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 10).Replace("\"", "");
}
var torrentPath = Path.Combine(path, fileName ?? "Arch Linux Distro");
if (File.Exists(torrentPath))
{
File.Delete(torrentPath);
}
Helper.Retry(() => wc.DownloadFile(new Uri(sLinkTorCache), torrentPath), TimeSpan.FromSeconds(3), 5);
}
Helper.Retry(出现HTTP异常时重试):
public static void Retry(Action action, TimeSpan retryInterval, int retryCount = 3)
{
Retry<object>(() =>
{
action();
return null;
}, retryInterval, retryCount);
}
public static T Retry<T>(Func<T> action, TimeSpan retryInterval, int retryCount = 3)
{
var exceptions = new List<Exception>();
for (int retry = 0; retry < retryCount; retry++)
{
try
{
if (retry > 0)
System.Threading.Thread.Sleep(retryInterval); // TODO adicionar o Using pro thread
return action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
我最初虽然网站认为这是来自机器人的请求(也就是说,它正在检查一些 headers),但它正在响应垃圾邮件。在查看 Fiddler 之后 - 看起来返回的数据对于网络浏览器和代码来说是完全相同的。这意味着,我们没有正确缩小(提取)响应。 Web 服务器压缩数据(使用类似 gzip 的东西)是很常见的。 WebClient
不会 自动缩减数据。
使用 Automatically decompress gzip response via WebClient.DownloadData 的答案 - 我设法让它正常工作。
另请注意,您正在下载该文件两次。你不需要那样做。
工作代码:
//Taken from above linked question
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
并使用它:
string sLinkTorCache = @"http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent";
using (var wc = new MyWebClient())
{
var path = @"C:\Junk";
var data = Helper.Retry(() => wc.DownloadData(sLinkTorCache), TimeSpan.FromSeconds(3), 5);
string fileName = "";
var torrentPath = Path.Combine(path, fileName ?? "Arch Linux Distro.torrent");
if (File.Exists(torrentPath))
File.Delete(torrentPath);
File.WriteAllBytes(torrentPath, data);
}