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

问题描述 投票:0回答:1

嗨,大家晚上好,我正在尝试实现一个类,它将处理http请求的seek函数,加载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个回答
0
投票

一直在玩,现在只是莫名其妙的工作。

    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;
                }
            }
© www.soinside.com 2019 - 2024. All rights reserved.