2012-12-07 32 views
16

मैं एक सार्वजनिक यूआरएल से बड़ी फाइल डाउनलोड करने का प्रयास कर रहा हूं। ऐसा लगता है कि पहले ठीक काम करता था लेकिन 1/10 कंप्यूटर टाइमआउट लगते थे। मेरा प्रारंभिक प्रयास WebClient.DownloadFileAsync का उपयोग करना था, लेकिन क्योंकि यह कभी पूरा नहीं होगा मैं WebRequest.Create का उपयोग करने के लिए वापस गिर गया और प्रतिक्रिया स्ट्रीम सीधे पढ़ा।WebRequest बड़ी फ़ाइलों (~ 1 जीबी) को ठीक से डाउनलोड करने में विफल रहता है

WebRequest.Create का उपयोग करने का मेरा पहला संस्करण WebClient.DownloadFileAsync जैसा ही समस्या पाया। ऑपरेशन का समय समाप्त होता है और फ़ाइल पूर्ण नहीं होती है।

मेरा अगला संस्करण डाउनलोड समय समाप्त होने पर रीट्रीज़ जोड़ा गया। यहां यह अजीब हो गया है। अंतिम 7092 बाइट्स को समाप्त करने के लिए डाउनलोड अंततः 1 पुनः प्रयास के साथ समाप्त होता है। इसलिए फ़ाइल को एक ही आकार के साथ डाउनलोड किया गया है लेकिन फ़ाइल दूषित है और स्रोत फ़ाइल से अलग है। अब मैं भ्रष्टाचार की उम्मीद करता हूं कि भ्रष्टाचार पिछले 70 9 2 बाइट्स में होगा लेकिन ऐसा नहीं है।

BeyondCompare का उपयोग करके मैंने पाया है कि दूषित फ़ाइल से लापता बाइट्स के 2 भाग गायब 7092 बाइट तक हैं! यह अनुपलब्ध बाइट 1CA49FF0 और 1E31F380 पर हैं, डाउनलोड समय से पहले और फिर से शुरू होने से पहले।

संभवतः यहां क्या हो सकता है? इस समस्या को और कैसे ट्रैक करें इस पर कोई संकेत?

यहां प्रश्न में कोड है।

public void DownloadFile(string sourceUri, string destinationPath) 
{ 
    //roughly based on: http://stackoverflow.com/questions/2269607/how-to-programmatically-download-a-large-file-in-c-sharp 
    //not using WebClient.DownloadFileAsync as it seems to stall out on large files rarely for unknown reasons. 

    using (var fileStream = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.Read)) 
    { 
     long totalBytesToReceive = 0; 
     long totalBytesReceived = 0; 
     int attemptCount = 0; 
     bool isFinished = false; 

     while (!isFinished) 
     { 
      attemptCount += 1; 

      if (attemptCount > 10) 
      { 
       throw new InvalidOperationException("Too many attempts to download. Aborting."); 
      } 

      try 
      { 
       var request = (HttpWebRequest)WebRequest.Create(sourceUri); 

       request.Proxy = null;//http://stackoverflow.com/questions/754333/why-is-this-webrequest-code-slow/935728#935728 
       _log.AddInformation("Request #{0}.", attemptCount); 

       //continue downloading from last attempt. 
       if (totalBytesReceived != 0) 
       { 
        _log.AddInformation("Request resuming with range: {0} , {1}", totalBytesReceived, totalBytesToReceive); 
        request.AddRange(totalBytesReceived, totalBytesToReceive); 
       } 

       using (var response = request.GetResponse()) 
       { 
        _log.AddInformation("Received response. ContentLength={0} , ContentType={1}", response.ContentLength, response.ContentType); 

        if (totalBytesToReceive == 0) 
        { 
         totalBytesToReceive = response.ContentLength; 
        } 

        using (var responseStream = response.GetResponseStream()) 
        { 
         _log.AddInformation("Beginning read of response stream."); 
         var buffer = new byte[4096]; 
         int bytesRead = responseStream.Read(buffer, 0, buffer.Length); 
         while (bytesRead > 0) 
         { 
          fileStream.Write(buffer, 0, bytesRead); 
          totalBytesReceived += bytesRead; 
          bytesRead = responseStream.Read(buffer, 0, buffer.Length); 
         } 

         _log.AddInformation("Finished read of response stream."); 
        } 
       } 

       _log.AddInformation("Finished downloading file."); 
       isFinished = true; 
      } 
      catch (Exception ex) 
      { 
       _log.AddInformation("Response raised exception ({0}). {1}", ex.GetType(), ex.Message); 
      } 
     } 
    } 
} 

यहाँ भ्रष्ट डाउनलोड से लॉग उत्पादन होता है:

Request #1. 
Received response. ContentLength=939302925 , ContentType=application/zip 
Beginning read of response stream. 
Response raised exception (System.Net.WebException). The operation has timed out. 
Request #2. 
Request resuming with range: 939295833 , 939302925 
Received response. ContentLength=7092 , ContentType=application/zip 
Beginning read of response stream. 
Finished read of response stream. 
Finished downloading file. 
+1

मैं अपने सिर के शीर्ष पर दो चीजें सोच सकता हूं। ए) बड़ी फ़ाइलों के लिए अपना टाइमआउट बढ़ाएं (यदि संभव हो) बी) क्या आपके एन्कोडिंग और डेटा को डीकोडिंग दूषित हो सकता है? मुझे एक बार एक अलग परियोजना पर यह समस्या थी। यूटीएफ -8 – Steven

+0

का उपयोग करके इसे एन्कोड करने का प्रयास करें यह एक एन्कोडिंग समस्या नहीं होनी चाहिए, यह एक बाइनरी ब्लॉब (ज़िप फ़ाइल) है। – Spish

+5

मुझे लगता है कि आप तार के गलत छोर पर एक सर्वर बग डीबग करने की कोशिश कर रहे हैं। –

उत्तर

0

इस विधि मैं आमतौर पर इस्तेमाल करते हैं, यह मेरे लोड हो रहा है उसी तरह आप की जरूरत के लिए अब तक विफल रहा है नहीं किया है। थोड़ा सा बदलने के लिए मेरे कोड का उपयोग करने का प्रयास करें और देखें कि क्या इससे मदद मिलती है।

if (!Directory.Exists(localFolder)) 
{ 
    Directory.CreateDirectory(localFolder); 
} 


try 
{ 
    HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(Path.Combine(uri, filename)); 
    httpRequest.Method = "GET"; 

    // if the URI doesn't exist, exception gets thrown here... 
    using (HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse()) 
    { 
     using (Stream responseStream = httpResponse.GetResponseStream()) 
     { 
      using (FileStream localFileStream = 
       new FileStream(Path.Combine(localFolder, filename), FileMode.Create)) 
      { 
       var buffer = new byte[4096]; 
       long totalBytesRead = 0; 
       int bytesRead; 

       while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0) 
       { 
        totalBytesRead += bytesRead; 
        localFileStream.Write(buffer, 0, bytesRead); 
       } 
      } 
     } 
    } 
} 
catch (Exception ex) 
{   
    throw; 
} 
0

आपको टाइमआउट सेटिंग्स को बदलना चाहिए। ऐसा लगता है कि दो संभावित टाइमआउट मुद्दे हैं:

  • क्लाइंट-साइड टाइमआउट - वेब क्लाइंट में टाइमआउट को बदलने का प्रयास करें। मुझे कभी-कभी बड़ी फ़ाइल डाउनलोड के लिए लगता है मुझे कभी ऐसा करने की ज़रूरत है।
  • सर्वर-साइड टाइमआउट - सर्वर पर टाइमआउट बदलने का प्रयास करें। आप यह सत्यापित कर सकते हैं कि यह किसी अन्य क्लाइंट का उपयोग कर समस्या है, उदा। PostMan
0

मेरे लिए बफरिंग द्वारा फ़ाइल को पढ़ने के तरीके पर आपकी विधि बहुत अजीब लगती है। हो सकता है कि समस्या है, जो आप कर

while(bytesRead > 0) 

क्या होगा अगर, किसी कारण से, धारा does not कोई बाइट्स कुछ बिंदु पर लौटने लेकिन यह अभी भी अभी तक समाप्त डाउनलोड नहीं है, तो यह पाश से बाहर निकलें और कभी नहीं आएगा वापस। आपको सामग्री-लंबाई प्राप्त करनी चाहिए, और बाइट्स रीड द्वारा प्राप्त एक चर कुल कुल वृद्धि करना चाहिए। अंत में आप लूप को

while(totalBytesReceived < ContentLength) 
संबंधित मुद्दे