2009-07-03 12 views
19

मुझे एक सी # कंसोल एप्लिकेशन में HTTP पर बड़ी फ़ाइल (2   जीबी) डाउनलोड करने की आवश्यकता है। समस्या है, लगभग 1.2   जीबी के बाद, एप्लिकेशन स्मृति से बाहर चला जाता है।मैं .NET में एक बड़ी फ़ाइल (HTTP के माध्यम से) कैसे डाउनलोड करूं?

यहाँ कोड मैं का उपयोग कर रहा है:

WebClient request = new WebClient(); 
request.Credentials = new NetworkCredential(username, password); 
byte[] fileData = request.DownloadData(baseURL + fName); 

आप देख सकते हैं ... मैं सीधे फ़ाइल पढ़ रहा हूँ स्मृति में। मुझे पूरा यकीन है कि मैं इसे हल कर सकता हूं अगर मैं डेटा से HTTP में वापस डेटा पढ़ना चाहता था और इसे डिस्क पर एक फ़ाइल में लिखना था।

मैं यह कैसे कर सकता हूं?

उत्तर

34

यदि आप WebClient.DownloadFile का उपयोग करते हैं तो आप इसे सीधे फ़ाइल में सहेज सकते हैं।

+0

प्रतिभा के बजाय यहां HttpClient का उपयोग करना संभव है। इसने अंत में एक सपना देखा। आपकी सहायताके लिए धन्यवाद! –

+0

एफवाईआई। इकाई क्लाइंट जैसे वेब क्लाइंट का परीक्षण करता है जो किसी भी इंटरफेस को लागू नहीं करता है चुनौतीपूर्ण हो सकता है। – Krishter

9

आपको प्रतिक्रिया स्ट्रीम प्राप्त करने और फिर ब्लॉक में पढ़ने की आवश्यकता है, प्रत्येक ब्लॉक को एक फ़ाइल में लिखने के लिए स्मृति को पुन: उपयोग करने की अनुमति देने के लिए।

जैसा कि आपने लिखा है, पूरी प्रतिक्रिया, सभी 2 जीबी, स्मृति में होना चाहिए। यहां तक ​​कि 64 बिट सिस्टम पर भी एक .NET ऑब्जेक्ट के लिए 2 जीबी सीमा को हिट करेगा।


अद्यतन: आसान विकल्प। आपके लिए काम करने के लिए WebClient प्राप्त करें: इसकी DownloadFile विधि के साथ जो डेटा को सीधे फ़ाइल में डाल देगा।

28

वेब क्लाइंट क्लास सरलीकृत परिदृश्यों में से एक है। एक बार जब आप पिछले सरल परिदृश्य (और आपके पास) प्राप्त कर लेते हैं, तो आपको थोड़ा सा वापस आना होगा और WebRequest का उपयोग करना होगा।

WebRequest के साथ, आपको प्रतिक्रिया स्ट्रीम तक पहुंच होगी, और आप इसे पूरा करने तक थोड़ा सा लिखने और थोड़ा लिखने में सक्षम होंगे।


उदाहरण:

public void MyDownloadFile(Uri url, string outputFilePath) 
{ 
    const int BUFFER_SIZE = 16 * 1024; 
    using (var outputFileStream = File.Create(outputFilePath, BUFFER_SIZE)) 
    { 
     var req = WebRequest.Create(url); 
     using (var response = req.GetResponse()) 
     { 
      using (var responseStream = response.GetResponseStream()) 
      { 
       var buffer = new byte[BUFFER_SIZE]; 
       int bytesRead; 
       do 
       { 
        bytesRead = responseStream.Read(buffer, 0, BUFFER_SIZE); 
        outputFileStream.Write(buffer, 0, bytesRead); 
       } while (bytesRead > 0); 
      } 
     } 
    } 
} 

ध्यान दें कि यदि WebClient.DownloadFile काम करता है, तो मैं यह सबसे अच्छा समाधान फोन चाहते हैं। मैंने "डाउनलोडफाइल" उत्तर पोस्ट करने से पहले उपरोक्त लिखा था। मैंने सुबह भी बहुत जल्दी लिखा, इसलिए नमक (और परीक्षण) का अनाज आवश्यक हो सकता है।

+0

आपके विस्तृत उत्तर और कोड स्निपेट के लिए धन्यवाद! यह उन मामलों में उपयोगी होगा जब मैं डेटा को संसाधित करना चाहता हूं! –

+0

इस कोड में अपवाद हैंडलिंग या पुनः प्रयास तंत्र के बारे में क्या? नेटवर्क डिस्कनेक्ट इत्यादि –

+0

ज्यादातर मामलों में, सबसे अच्छा अपवाद हैंडलिंग बिल्कुल भी नहीं है। यदि आप ऐसी परिस्थिति में हैं जहां आपका नेटवर्क बहुत अविश्वसनीय है, तो आपको पुनः प्रयास तर्क जोड़ने की आवश्यकता हो सकती है। मैं संयुक्त राज्य अमेरिका में रहता हूं, इसलिए मुझे लगता है कि मैं अच्छे नेटवर्क कनेक्शन, _usually_ द्वारा खराब हो गया हूं। जब वे काम नहीं करते हैं, तो चीजें इतनी खराब होती हैं कि पुनः प्रयास एक उपयोगी विकल्प नहीं है। –

2

कुछ WebClient.OpenRead एक स्ट्रीम देता है, बस सामग्री पर पाश के लिए पढ़ें उपयोग करते हैं, तो डेटा स्मृति में बफ़र नहीं है, लेकिन एक फाइल करने के लिए ब्लॉकों में लिखा जा सकता है का प्रयोग करेंगे।

संबंधित मुद्दे