2009-09-17 9 views
6

मैं एक प्रोग्राम बना रहा हूं जो http पर फ़ाइलों को डाउनलोड करता है।यह स्ट्रीम तलाश संचालन का समर्थन नहीं करती है। HttpWebResponse

मुझे यह डाउनलोड हो गया है, हालांकि मैं डाउनलोड को रोकने, प्रोग्राम को बंद करने और बाद की तारीख में फिर से शुरू करने में सक्षम होना चाहता हूं।

मुझे पता है कि मैं उन्हें समर्थन से डाउनलोड कर रहा हूं।

मैं HttpWebResponse के माध्यम से फ़ाइल डाउनलोड कर रहा हूं और GetResponseStream का उपयोग कर स्ट्रीम में प्रतिक्रिया पढ़ रहा हूं।

जब मैं ऐप बंद करता हूं और इसे पुनरारंभ करता हूं, तो मैं डाउनलोड को फिर से शुरू करने के लिए अटक गया हूं। मैंने स्ट्रीम पर एक खोज करने की कोशिश की है लेकिन यह बताता है कि यह समर्थित नहीं है।

ऐसा करने का सबसे अच्छा तरीका क्या होगा?

+0

ध्यान रखें कि आपको सर्वर को पुनरारंभ करने के लिए कहना है - आप इसे स्वयं नहीं कर सकते हैं। नीचे 'AddRange' उत्तर का यही कारण है। –

उत्तर

9

सर्वर इस आप अपने अनुरोध AddRange विधि का उपयोग कर के साथ Range HTTP शीर्ष लेख भेजने के लिए समर्थन करता है, तो:

request.AddRange(1024); 

इस सर्वर 1 किलोबाइट के बाद फ़ाइल भेजना प्रारंभ करने के निर्देश देगा। फिर सामान्य प्रतिक्रिया के रूप में प्रतिक्रिया स्ट्रीम पढ़ें।

यह जांचने के लिए कि कोई सर्वर फिर से शुरू करने का समर्थन करता है, तो आप HEAD अनुरोध और परीक्षण भेज सकते हैं यदि यह Accept-Ranges: bytes शीर्षलेख भेजता है।

+5

क्या आप एमएसडीएन दस्तावेज़ों में एक लिंक जोड़ना चाहते हैं? http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.addrange.aspx –

2

HTTPRangeStream क्लास के बारे में कैसे?

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using System.Text; 

namespace Ionic.Kewl 
{ 
    public class HTTPRangeStream : Stream 
    { 
     private string url; 
     private long length; 
     private long position; 
     private long totalBytesRead; 
     private int totalReads; 

     public HTTPRangeStream(string URL) 
     { 
      url = URL; 
      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); 
      HttpWebResponse result = (HttpWebResponse)request.GetResponse(); 
      length = result.ContentLength; 
     } 

     public long TotalBytesRead { get { return totalBytesRead; } } 
     public long TotalReads  { get { return totalReads; } } 
     public override bool CanRead { get { return true; } } 
     public override bool CanSeek { get { return true; } } 
     public override bool CanWrite { get { return false; } } 
     public override long Length { get { return length; } } 

     public override bool CanTimeout 
     { 
      get 
      { 
       return base.CanTimeout; 
      } 
     } 


     public override long Position 
     { 
      get 
      { 
       return position; 
      } 
      set 
      { 
       if (value < 0) throw new ArgumentException(); 
       position = value; 
      } 
     } 

     public override long Seek(long offset, SeekOrigin origin) 
     { 
      switch (origin) 
      { 
       case SeekOrigin.Begin: 
        position = offset; 
        break; 
       case SeekOrigin.Current: 
        position += offset; 
        break; 
       case SeekOrigin.End: 
        position = Length + offset; 
        break; 
       default: 
        break; 
      } 
      return Position; 
     } 

     public override int Read(byte[] buffer, int offset, int count) 
     { 
      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); 
      request.AddRange(Convert.ToInt32(position), Convert.ToInt32(position) + count); 
      HttpWebResponse result = (HttpWebResponse)request.GetResponse(); 
      using (Stream stream = result.GetResponseStream()) 
      { 
       stream.Read(buffer, offset, count); 
       stream.Close(); 
      } 
      totalBytesRead += count; 
      totalReads++; 
      Position += count; 
      return count; 
     } 


     public override void Write(byte[] buffer, int offset, int count) 
     { 
      throw new NotSupportedException(); 
     } 

     public override void SetLength(long value) 
     { 
      throw new NotSupportedException(); 
     } 
     public override void Flush() 
     { 
      throw new NotSupportedException(); 
     } 

    } 
} 
+0

क्या यह कक्षा तब भी काम करती है जब सर्वर फिर से स्वीकार नहीं करता है? – Smith

+0

मुझे नहीं पता कि "फिर से शुरू" क्या है। HTTP 1.1 एक श्रेणी शीर्षलेख परिभाषित करता है, जो इस वर्ग पर निर्भर करता है। यदि सर्वर HTTP 1.1 करता है, तो यह रेंज करता है, और इस वर्ग से संपर्क किया जा सकता है। 'रेज़्यूमिंग' द्वारा – Cheeso

+0

मेरा मतलब था 'रेंज हेडर', स्पष्टीकरण के लिए धन्यवाद – Smith

0

आपका समाधान ठीक है, लेकिन यह केवल उन मामलों के लिए काम करेगा जहां सर्वर सामग्री-लंबाई शीर्षलेख भेजता है। यह हेडर गतिशील रूप से जेनरेट की गई सामग्री में मौजूद नहीं होगा।

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

मैं डेटा को स्थानीय रूप से संग्रहीत करके, या तो डिस्क या स्मृति में, इस पर सुधार करूंगा। फिर, आप जो चाहें उसे खोज सकते हैं। असंगतता की कोई समस्या नहीं होगी, और आपको इसे डाउनलोड करने के लिए केवल एक HttpWebRequest की आवश्यकता है।