varios net form desde descargar archivos archivo c# download webclient

net - webclient c#



Descarga de mĂșltiples archivos WebClient (2)

Intento descargar varios archivos pero no funciona como esperaba. ¿Puede alguien decirme qué pasa con este guión, porque he probado muchas cosas y ya no sé qué hacer?

public static void DownloadFile(string url) { WebClient client = new WebClient(); var name = url.Substring(url.LastIndexOf(''/'')).Remove(0, 1); foreach (var item in urls) { client.DownloadFile(item, "C://" + name); } } private void btnGo_Click(object sender, EventArgs e) { urls.Add("url1"); urls.Add("url2"); urls.Add("url3"); Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile); }

using (var sr = new StreamReader(HttpWebRequest.Create(url).GetResponse().GetResponseStream())) { using (var sw = new StreamWriter(url.Substring(url.LastIndexOf(''/'')))) { sw.Write(sr.ReadToEnd()); } }


Está descargando todos los archivos al mismo archivo en su código de DownloadFile, que asume que una sola llamada a esta función descarga todos los archivos.

Correcciones:

Opción 1: No use Parallel.ForEach y simplemente llame a DownloadFile una vez. Especifique nombres de archivo únicos para cada descarga. Es decir, al tomar parte de Url que está descargando o simplemente utilizando nombres de archivo aleatorios / temporales.

Algo como esto (suponiendo que las URL son algún tipo de IEnumerable<string> )

foreach (var item in urls) { var name = item.Substring(item.LastIndexOf(''/'')).Remove(0, 1); client.DownloadFile(item, "C://" + name); }

Opción 2: Use Parallel.ForEach pero cambie el código DownloadFile para descargar solo un archivo:

public static void DownloadFile(string url) { WebClient client = new WebClient(); var name = url.Substring(url.LastIndexOf(''/'')).Remove(0, 1); client.DownloadFile(url, "C://" + name); }


Yo usaría una System.Net.HttpWebRequest lugar.

Así es como se vería el código:

private List<string> urls = new List<string>(); private void btnGo_Click(object sender, EventArgs e) { urls.Add("http://199.91.152.106/ua0p3fbc5nlg/gg2w2fq4ljc1nnd/MicroCraft_Beta.zip"); Parallel.ForEach(urls, new ParallelOptions { MaxDegreeOfParallelism = 10 }, DownloadFile); } public static void DownloadFile(string url) { var req = (HttpWebRequest)WebRequest.Create(url); var name = url.Substring(url.LastIndexOf(''/'') + 1); using (var res = (HttpWebResponse)req.GetResponse()) using (var resStream = res.GetResponseStream()) using (var fs = new FileStream("C://" + name, FileMode.Create, FileAccess.Write, FileShare.None)) { // Save to file var buffer = new byte[8 * 1024]; // 8 KB buffer int len; // Read count while ((len = resStream.Read(buffer, 0, buffer.Length)) > 0) fs.Write(buffer, 0, buffer.Length); } }

Porque la URL que me dijo en el comentario no utiliza una implementación adecuada del protocolo HTTP. Deberá agregar esto a su archivo de configuración para que funcione (ya sea App.config o Web.config, dependiendo de si es un sitio ASP.Net o una aplicación fuera de línea):

<system.net> <settings> <httpWebRequest useUnsafeHeaderParsing="true" /> </settings> </system.net>

En cuanto a su problema con los nombres que colisionan, que dijo en su comentario, esto debería resolverse cambiando su var name = url.Substring(url.LastIndexOf(''/'')).Remove(0, 1); en otra cosa.

Si desea tener un nombre de archivo incremental, puede usar esto:

// Inside your class: private static int counter = 0; // In your method: var name = "file" + System.Threading.Interlocked.Increment(ref counter) + ".html";