2016-01-26 2 views
1

Je souhaite télécharger un fichier .torrent à partir d'une distribution Linux, mais pour une raison quelconque, le dernier fichier téléchargé depuis mon application est différent de celui téléchargé manuellement. Celui que mon application télécharge a 31KB et c'est un fichier .torrent invalide, alors que le droit (quand je le télécharge manuellement) a 41KB et il est valide.WebClient ne télécharge pas le bon fichier à partir de l'URL fournie

L'URL du fichier que je veux télécharger est http://torcache.net/torrent/C348CBCA08288AE07A97DD641C5D09EE25299FAC.torrent

Pourquoi cela se produit et comment puis-je télécharger le même fichier (le valide, avec 41Ko)?

Merci.


C# Code de la méthode qui télécharge le fichier ci-dessus:

 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 (Essayez d'exécuter la méthode à nouveau en cas d'exceptions 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); 
    } 
+0

Pourquoi télécharger le fichier que vous deux fois dans votre code? 'DownloadData' et' DownloadFile' – Rob

Répondre

1

J'ai d'abord pensé h le site répondait avec des indésirables s'il pensait que c'était une requête d'un bot (c'est-à-dire qu'il vérifiait certains en-têtes). Après avoir regardé avec Fiddler - il semble que les données retournées soient exactement les mêmes pour un navigateur Web et le code. Ce qui signifie que nous ne dégonflons pas correctement (en extrayant) la réponse. Il est très commun pour les serveurs Web de compresser les données (en utilisant quelque chose comme gzip). WebClient ne pas automatiquement dégonfler les données.

En utilisant la réponse de Automatically decompress gzip response via WebClient.DownloadData - J'ai réussi à le faire fonctionner correctement.

Notez également que vous téléchargez le fichier deux fois. Vous n'avez pas besoin de faire ça.

Code de travail:

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

Et l'utiliser:

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

Merci Rob, ça a marché! –