Me gustaría utilizar el WebClient
(¿o hay otra opción mejor?) Pero hay un problema. Entiendo que abrir el flujo lleva algo de tiempo y esto no se puede evitar. Sin embargo, leerlo toma una cantidad de tiempo mucho más extraña en comparación con leerlo completamente de inmediato.¿Cómo descargar un archivo en una cadena con una devolución de llamada de progreso?
¿Existe alguna forma de hacerlo? Me refiero a dos formas, a la cadena y al archivo. Progress
es mi propio delegado y está funcionando bien.
ACTUALIZACIÓN QUINTO:
Finalmente, logró hacerlo. Mientras tanto, verifiqué algunas soluciones que me hicieron darme cuenta de que el problema está en otra parte.
He probado objetos personalizados WebResponse
y WebRequest
, biblioteca libCURL.NET
e incluso Sockets
.
La diferencia en el tiempo fue la compresión gzip. La duración de la secuencia comprimida era simplemente la mitad de la duración normal de la transmisión y, por lo tanto, el tiempo de descarga era inferior a 3 segundos con el navegador.
que poner un poco de código si alguien va a querer saber cómo resolví esto: (no se necesitan algunas cabeceras)
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;
}
Creo que funciona asyncro serán casi los mismos. Pero simplemente usaré otro hilo para activar esta función. No necesito una indicación de progreso precisa.
¿Qué exactamente no es tan bueno? ¿Dónde está la cuerda a la que escribes? – Marcel
No es bueno porque el resultado es solo 2048 caracteres (iSize) del final del archivo. Y es muy lento para descargar todo. – Kaminari
Parece que estás leyendo ese mismo 'Stream' en dos lugares; 'reader' y' streamRemote' ... Estoy confundido ... También; cuidado: cuando maneja bytes, no siempre lee bloques ('iByteSize') que son números enteros de caracteres. Tampoco está muy claro cómo las actualizaciones de UI suceden en la devolución de llamada; si esto implica un cambio de hilo que agregará retrasos (como lo hará el maldito 'DoEvents'). –