简体   繁体   English

WebClient没有从提供的URL下载正确的文件

[英]WebClient isn't downloading the right file from the supplied URL

I want to download a .torrent file from a Linux distro, but for some reason the final file downloaded from my app is different from the one downloaded manually. 我想从Linux发行版下载.torrent文件,但由于某种原因,从我的应用程序下载的最终文件与手动下载的文件不同。 The one that my app downloads has 31KB and it is a invalid .torrent file, while right one (when i download manually) has 41KB and it is valid. 我的应用下载的文件有31KB,它是一个无效的.torrent文件,而正确的文件(当我手动下载时)有41KB,它是有效的。

The URL from the file i want to download is http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent 我要下载的文件的URL是http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent

Why is it happening and how can i download the same file (the valid one, with 41KB)? 为什么会发生这种情况,如何下载同一文件(有效文件,大小为41KB)?

Thanks. 谢谢。


C# Code from the method that downloads the file above: 下载上面文件的方法中的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 (Try to execute the method again in case of HTTP Exceptions): 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);
    }

I initially though the site was responding with junk if it thought it was a request from a bot (that is, it was checking some of the headers). 最初,虽然该网站认为它是来自漫游器的请求(也就是说,它正在检查某些标头),但我的响应是垃圾。 After having a look with Fiddler - it appears that the data returned is exactly the same for both a web browser and the code. 在看了Fiddler之后 -看来对于Web浏览器和代码返回的数据是完全相同的。 Which means, we're not properly deflating (extracting) the response. 这意味着,我们没有正确缩小(提取)响应。 It's very common for web servers to compress the data (using something like gzip). Web服务器压缩数据(使用gzip之类的数据)非常普遍。 WebClient does not automatically deflate the data. WebClient 不会自动收缩数据。

Using the answer from Automatically decompress gzip response via WebClient.DownloadData - I managed to get it to work properly. 使用通过WebClient.DownloadData自动解压缩gzip响应中的答案-我设法使其正常工作。

Also note that you're downloading the file twice. 另请注意,您将文件下载两次。 You don't need to do that. 您不需要这样做。

Working code: 工作代码:

//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;
    }
}

And using it: 并使用它:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM