【问题标题】:HTTP Stream Implementation To Load Remote ZIP Files Just Like Local Files - DotNetZip像本地文件一样加载远程 ZIP 文件的 HTTP 流实现 - DotNetZip
【发布时间】:2020-04-24 19:32:02
【问题描述】:

大家好,晚上好/早上好,所以我正在尝试实现一个类来处理 http 请求的查找功能,以加载 zip 文件并在旅途中提取特定文件,而不是下载所有存档,到目前为止它在开始时运行良好,但随着它的进一步发展,丢失了一些文件,或者永远获取库存,我编写的类如下所示:(我从 github 上的某个地方获取并真正修改了它)

public class HTTPDownloadStream : Stream
{
    private string _serverUri;
    private MemoryStream StoringStream = null;

    private HttpWebRequest _request;
    private HttpWebResponse _response;
    private Stream _responseStream = null;
    public Exception CaughtException;
    private long TotalLength = 0;
    public long BytePlace = 0;
    public long LoadRange = 0;
    public HTTPDownloadStream(string serverUri)
    {
        _serverUri = serverUri;
        StartHTTPDOwnload();
    }

    private void StartHTTPDOwnload(long from = 0)
    {
        // This can be replaced with the Http equivalents
        _request = (HttpWebRequest)WebRequest.Create(_serverUri);

        _request.AddRange(from);
        LoadRange = from;

        _response = (HttpWebResponse)_request.GetResponse();
        _responseStream = _response.GetResponseStream();
        if(TotalLength == 0)
        {
            TotalLength = _response.ContentLength;
        }
        if (StoringStream != null)
        {
            StoringStream.Close();
        }
        StoringStream = new MemoryStream();
        int readbytes = 0;
        while (true)
        {
            byte[] readdata = new byte[4096];
            int len = _responseStream.Read(readdata, 0, readdata.Length);
            readbytes += len;
            if (len > 0 && readbytes < 102000)
            {
                StoringStream.Write(readdata, 0, len);
            }
            else
            {
                break;
            }
        }
        StoringStream.Position = 0;

        _responseStream.Close();
        _response.Close();
        _responseStream = null;
        _response = null;
        _request = null;
        //if (_responseStream != null)
        //  _responseStream.ReadTimeout = 10000;    // Set timeout to 10 seconds for testing.
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int attempts = 0;
        // Adjust the maximum attempts according to your needs
        while (attempts++ < 5)
        {
            if (StoringStream == null)
            {
                StartHTTPDOwnload();
            }

            try
            {
                // This will throw a timeout exception if the connection is interrupted.
                // Will throw null exception if failed to open (start); this will also retry.
                int done = StoringStream.Read(buffer, offset, count);
                BytePlace += done;
                long placereached = (BytePlace  - LoadRange);
                if(placereached >= StoringStream.Length)
                {
                    Seek(1, SeekOrigin.Current);
                    int ndone = StoringStream.Read(buffer, done, count - done);
                    BytePlace += ndone;
                    done += ndone;
                }
                return done;
            }
            catch (Exception ex)
            {
                CaughtException = ex;
                // Close ftp resources if possible. Set instances to null to force restart. 
                Close();
            }
        }
        return 0;
    }

    public override void Close()
    {
        if (_responseStream != null)
        {
            try
            {
                StoringStream.Close();
            }
            catch
            {
                // No action required
            }
        }
        StoringStream = null;
    }

    // Implement the Stream methods
    public override void Flush()
    {
        StoringStream.Flush();
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        if(origin == SeekOrigin.Begin)
        {
            BytePlace = offset;
        }
        else
        {
            BytePlace += offset;
        }

        long newplace = BytePlace - LoadRange;
        if(newplace < 0 || newplace >= StoringStream.Length)
        {
            StartHTTPDOwnload((BytePlace));
        }
        else
        {
            StoringStream.Seek(newplace, SeekOrigin.Begin);
        }

        return BytePlace;
    }

    public override void SetLength(long value)
    {
        StoringStream.SetLength(value);
    }
    public override void Write(byte[] buffer, int offset, int count)
    {
        StoringStream.Write(buffer, offset, count);
    }

    public override bool CanRead
    {
        get { return StoringStream.CanRead; }
    }
    public override bool CanSeek
    {
        get { return StoringStream.CanSeek;  }
    }
    public override bool CanWrite
    {
        get { return StoringStream.CanWrite; }
    }
    public override long Length
    {
        get { return TotalLength; }
    }
    public override long Position
    {
        get { return BytePlace; }
        set { BytePlace = value; } // never gets called, no worries
    }
}

使用它:

HTTPDownloadStream httpstream = new HTTPDownloadStream("http://update.dbankcdn.com/TDS/data/files/p3/s15/G5398/g1755/v386379/f1/full/update_full_base.zip");
ZipInputStream stream = new ZipInputStream(httpstream);
while(true)
{
    ZipEntry entry = stream.GetNextEntry();
    if(entry != null)
    {
        MessageBox.Show(entry.FileName + " | " + entry.CompressedSize);
    }
    else
    {
        MessageBox.Show("Done");

    }              
}

我真的不知道自己缺少什么,任何帮助都会非常非常非常感激。

【问题讨论】:

    标签: c# http stream zip remote-access


    【解决方案1】:

    一直在玩它,现在它只是以某种方式工作

        class HTTPStream : Stream
        {
            private string _serverUri;
            private MemoryStream StoringStream = null;
    
            private HttpWebRequest _request;
            private HttpWebResponse _response;
            private Stream _responseStream = null;
            public Exception CaughtException;
            private long TotalLength = 0;
            public long BytePlace = 0;
            public long LoadRange = 0;
            public HTTPStream(string serverUri)
            {
                _serverUri = serverUri;
                StartHTTPDOwnload();
            }
    
            private void StartHTTPDOwnload(long from = 0)
            {
                _request = (HttpWebRequest)WebRequest.Create(_serverUri);
    
                _request.AddRange(from, from + 300000);
                LoadRange = from;
                _response = (HttpWebResponse)_request.GetResponse();
                _responseStream = _response.GetResponseStream();
                if (TotalLength == 0)
                {
                    TotalLength = _response.ContentLength;
                }
                if (StoringStream != null)
                {
                    StoringStream.Close();
                }
                StoringStream = new MemoryStream();
                int readbytes = 0;
                while (true)
                {
                    byte[] readdata = new byte[4096];
                    int len = _responseStream.Read(readdata, 0, readdata.Length);
                    readbytes += len;
                    if (len > 0 && readbytes < 250000)
                    {
                        StoringStream.Write(readdata, 0, len);
                    }
                    else
                    {
                        break;
                    }
                }
                StoringStream.Position = 0;
    
                _responseStream.Close();
                _response.Close();
                _responseStream = null;
                _response = null;
                _request = null;
            }
    
            public override int Read(byte[] buffer, int offset, int count)
            {
                int attempts = 0;
                while (attempts++ < 5)
                {
                    if (StoringStream == null)
                    {
                        StartHTTPDOwnload();
                    }
    
                    try
                    {
                        int done = StoringStream.Read(buffer, offset, count);
                        BytePlace += done;
                        long placereached = (BytePlace - LoadRange);
                        if (placereached >= StoringStream.Length)
                        {
                            Seek(0, SeekOrigin.Current);
                            int ndone = StoringStream.Read(buffer, done, count - done);
                            BytePlace += ndone;
                            done += ndone;
                        }
                        return done;
                    }
                    catch (Exception ex)
                    {
                        CaughtException = ex;
                        Close();
                    }
                }
                return 0;
            }
    
            public override void Close()
            {
                if (StoringStream != null)
                {
                    try
                    {
                        StoringStream.Close();
                    }
                    catch
                    {
    
                    }
                }
                StoringStream = null;
            }
    
            public override void Flush()
            {
                StoringStream.Flush();
            }
    
            public override long Seek(long offset, SeekOrigin origin)
            {
    
                if (origin == SeekOrigin.Begin)
                {
                    BytePlace = offset;
                }
                else
                {
                    BytePlace += offset;
                }
    
                long newplace = BytePlace - LoadRange;
                if (newplace < 0 || newplace >= StoringStream.Length)
                {
                    StartHTTPDOwnload((BytePlace));
                }
                else
                {
                    StoringStream.Seek(newplace, SeekOrigin.Begin);
                }
                return BytePlace;
            }
    
            public override void SetLength(long value)
            {
                StoringStream.SetLength(value);
            }
            public override void Write(byte[] buffer, int offset, int count)
            {
                StoringStream.Write(buffer, offset, count);
            }
    
            public override bool CanRead
            {
                get { return StoringStream.CanRead; }
            }
            public override bool CanSeek
            {
                get { return StoringStream.CanSeek; }
            }
            public override bool CanWrite
            {
                get { return StoringStream.CanWrite; }
            }
            public override long Length
            {
                get { return TotalLength; }
            }
            public override long Position
            {
                get { return BytePlace; }
                set { BytePlace = value; } // never gets called, no worries
            }
        }
    
                HTTPStream httpstream = new HTTPStream(GetPackageURL(url));
                ZipInputStream stream = new ZipInputStream(httpstream);
                while (true)
                {
                    ZipEntry entry = stream.GetNextEntry();
                    if (entry != null)
                    {
                        if (entry.Name.Contains("SOFTWARE_VER_LIST.mbn"))
                        {                       
                            int read = 4096;
                            byte[] buffer = new byte[read];
                            string content = "";
                            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                content += Encoding.UTF8.GetString(buffer, 0, read);
                            }
                            romDetails.SupportedVersions = content.Split('\n');
                            break;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Seems like I couldn't load some data :(", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                    }
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 2011-09-11
      相关资源
      最近更新 更多