Vorrei utilizzare lo WebClient
(o c'è un'altra opzione migliore?) Ma c'è un problema. Capisco che l'apertura del flusso richiede un po 'di tempo e questo non può essere evitato. Tuttavia, leggerlo richiede una quantità stranamente molto più lunga rispetto a leggerlo interamente immediatamente.Come scaricare il file in una stringa con callback progressivo?
C'è un modo migliore per farlo? Intendo due modi, stringere e archiviare. Progress
è il mio delegato e funziona bene.
AGGIORNAMENTO QUINTO:
Infine, sono riuscito a farlo. Nel frattempo ho verificato alcune soluzioni che mi hanno fatto capire che il problema sta altrove.
Ho testato gli oggetti personalizzati WebResponse
e WebRequest
, libreria libCURL.NET
e anche Sockets
.
La differenza di tempo è stata la compressione gzip. La durata del flusso compresso era semplicemente la metà della normale durata del flusso e quindi il tempo di download era inferiore a 3 secondi con il browser.
ho messo un po 'di codice, se qualcuno vorrà sapere come ho risolto in questo modo: (alcune intestazioni non sono necessari)
public static string DownloadString(string URL)
{
WebClient client = new WebClient();
client.Headers["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1045 Safari/532.5";
client.Headers["Accept"] = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
client.Headers["Accept-Encoding"] = "gzip,deflate,sdch";
client.Headers["Accept-Charset"] = "ISO-8859-2,utf-8;q=0.7,*;q=0.3";
Stream inputStream = client.OpenRead(new Uri(URL));
MemoryStream memoryStream = new MemoryStream();
const int size = 32 * 4096;
byte[] buffer = new byte[size];
if (client.ResponseHeaders["Content-Encoding"] == "gzip")
{
inputStream = new GZipStream(inputStream, CompressionMode.Decompress);
}
int count = 0;
do
{
count = inputStream.Read(buffer, 0, size);
if (count > 0)
{
memoryStream.Write(buffer, 0, count);
}
}
while (count > 0);
string result = Encoding.Default.GetString(memoryStream.ToArray());
memoryStream.Close();
inputStream.Close();
return result;
}
Penso che funzioni asyncro sarà quasi lo stesso. Ma userò semplicemente un altro thread per attivare questa funzione. Non ho bisogno dell'indicazione di progresso di percise.
Che cosa esattamente non è così buono? Dov'è la stringa su cui scrivi? – Marcel
Non è buono perché il risultato è solo 2048 (iSize) caratteri dalla fine del file. Ed è molto lento a scaricare tutto. – Kaminari
Sembra che tu stia leggendo lo stesso 'Stream' in due posti; 'reader' e' streamRemote' ... Sono confuso ... Inoltre; attenzione: quando si gestiscono i byte non si leggono sempre i blocchi ('iByteSize') che sono numeri interi di caratteri. Inoltre non è molto chiaro come gli aggiornamenti dell'interfaccia utente si verificano nella richiamata; se questo implica un thread-switch che aggiungerà ritardi (così come il maledetto 'DoEvents'). –