Sto tentando di scaricare un file di grandi dimensioni da un URL pubblico. All'inizio sembrava funzionare bene, ma i computer 1/10 sembrano scadere. Il mio tentativo iniziale era di usare WebClient.DownloadFileAsync
ma, poiché non sarebbe mai stato completato, ricado all'utilizzo di WebRequest.Create
e leggere direttamente i flussi di risposta.WebRequest non riesce a scaricare correttamente i file di grandi dimensioni (~ 1 GB)
La mia prima versione di utilizzo di WebRequest.Create
ha riscontrato lo stesso problema di WebClient.DownloadFileAsync
. L'operazione scade e il file non viene completato.
La mia prossima versione ha aggiunto tentativi se il download è scaduto. Qui è che è strano. Il download termina con 1 tentativo di finire gli ultimi 7092 byte. Quindi il file viene scaricato con esattamente la stessa dimensione, MA il file è corrotto e si differenzia dal file sorgente. Ora mi aspetterei che la corruzione sia negli ultimi 7092 byte ma non è questo il caso.
Utilizzo di BeyondCompare Ho trovato che ci sono 2 blocchi di byte mancanti dal file corrotto per un totale di 7092 byte mancanti! Questi byte mancanti sono 1CA49FF0
e 1E31F380
, molto prima che il download scada e venga riavviato.
Cosa potrebbe succedere qui? Qualche suggerimento su come rintracciare ulteriormente questo problema?
Questo è il codice in questione.
public void DownloadFile(string sourceUri, string destinationPath)
{
//roughly based on: http://stackoverflow.com/questions/2269607/how-to-programmatically-download-a-large-file-in-c-sharp
//not using WebClient.DownloadFileAsync as it seems to stall out on large files rarely for unknown reasons.
using (var fileStream = File.Open(destinationPath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
long totalBytesToReceive = 0;
long totalBytesReceived = 0;
int attemptCount = 0;
bool isFinished = false;
while (!isFinished)
{
attemptCount += 1;
if (attemptCount > 10)
{
throw new InvalidOperationException("Too many attempts to download. Aborting.");
}
try
{
var request = (HttpWebRequest)WebRequest.Create(sourceUri);
request.Proxy = null;//http://stackoverflow.com/questions/754333/why-is-this-webrequest-code-slow/935728#935728
_log.AddInformation("Request #{0}.", attemptCount);
//continue downloading from last attempt.
if (totalBytesReceived != 0)
{
_log.AddInformation("Request resuming with range: {0} , {1}", totalBytesReceived, totalBytesToReceive);
request.AddRange(totalBytesReceived, totalBytesToReceive);
}
using (var response = request.GetResponse())
{
_log.AddInformation("Received response. ContentLength={0} , ContentType={1}", response.ContentLength, response.ContentType);
if (totalBytesToReceive == 0)
{
totalBytesToReceive = response.ContentLength;
}
using (var responseStream = response.GetResponseStream())
{
_log.AddInformation("Beginning read of response stream.");
var buffer = new byte[4096];
int bytesRead = responseStream.Read(buffer, 0, buffer.Length);
while (bytesRead > 0)
{
fileStream.Write(buffer, 0, bytesRead);
totalBytesReceived += bytesRead;
bytesRead = responseStream.Read(buffer, 0, buffer.Length);
}
_log.AddInformation("Finished read of response stream.");
}
}
_log.AddInformation("Finished downloading file.");
isFinished = true;
}
catch (Exception ex)
{
_log.AddInformation("Response raised exception ({0}). {1}", ex.GetType(), ex.Message);
}
}
}
}
Ecco l'output del registro dal download corrotto:
Request #1.
Received response. ContentLength=939302925 , ContentType=application/zip
Beginning read of response stream.
Response raised exception (System.Net.WebException). The operation has timed out.
Request #2.
Request resuming with range: 939295833 , 939302925
Received response. ContentLength=7092 , ContentType=application/zip
Beginning read of response stream.
Finished read of response stream.
Finished downloading file.
Potrei pensare a due cose in cima alla mia testa. a) Aumentare il timeout per i file di grandi dimensioni (se possibile) b) la codifica e la decodifica dei dati potrebbero essere danneggiati? Ho avuto questo problema su un progetto diverso che avevo una volta. Prova a codificarlo usando UTF-8 – Steven
Non dovrebbe essere un problema di codifica, è un blob binario (file zip). – Spish
Sembra che tu stia cercando di eseguire il debug di un bug del server sulla parte sbagliata del cavo. –