Всем привет и добрый вечер / утро, поэтому я пытаюсь реализовать класс, который будет обрабатывать функции поиска http-запроса, загружать zip-файл (ы) и извлекать определенные c файлы на go Вместо того, чтобы загружать весь архив, пока он хорошо работает в начале, но, как только он идет дальше, пропускает некоторые файлы или навсегда заполняется, класс, который я написал, выглядит следующим образом: (Я взял его где-то на 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");
}
}
Я действительно не знаю, чего мне не хватает, любая помощь будет очень, очень, очень признательна.