简体   繁体   English

HTTP Stream 实现加载远程 ZIP 文件就像本地文件一样 - DotNetZip

[英]HTTP Stream Implementation To Load Remote ZIP Files Just Like Local Files - DotNetZip

Hi and good evening / morning everyone, so I'm trying to implementation a class which would handle the seek functions of an http request, to load zip file(s) and extract specific files on the go rather than downloading all the archive, so far it works well at the beginning but as it goes further, misses some files, or gets stock forever, the class I've written is like below: ( I took it from somewhere on github and really modified it ) Hi and good evening / morning everyone, so I'm trying to implementation a class which would handle the seek functions of an http request, to load zip file(s) and extract specific files on the go rather than downloading all the archive, so到目前为止,它在开始时运行良好,但随着它的进一步发展,错过了一些文件,或者永远存货,我写的 class 如下所示:(我从 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
    }
}

Using it:使用它:

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");

    }              
}

I really don't know what I'm missing around, any help would be really, really, really appreciated.我真的不知道自己缺少什么,任何帮助都会非常非常非常感谢。

Been playing around with it and now it just somehow working一直在玩它,现在它只是以某种方式工作

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM