Cómo obtener el tamaño del archivo de encabezados http

Quiero obtener el tamaño de un archivo http: /…/ antes de descargarlo. El archivo puede ser una página web, una imagen o un archivo multimedia. ¿Se puede hacer esto con los encabezados HTTP? ¿Cómo descargo solo el encabezado HTTP del archivo?

Sí, suponiendo que el servidor HTTP con el que está hablando lo admite / permite esto:

System.Net.WebRequest req = System.Net.HttpWebRequest.Create("http://stackoverflow.com/robots.txt"); req.Method = "HEAD"; using (System.Net.WebResponse resp = req.GetResponse()) { int ContentLength; if(int.TryParse(resp.Headers.Get("Content-Length"), out ContentLength)) { //Do something useful with ContentLength here } } 

Si no se permite el uso del método HEAD, o el encabezado Content-Length no está presente en la respuesta del servidor, la única forma de determinar el tamaño del contenido en el servidor es descargarlo. Como esto no es particularmente confiable, la mayoría de los servidores incluirán esta información.

¿Se puede hacer esto con los encabezados HTTP?

Sí, este es el camino a seguir. Si se proporciona la información, está en el encabezado como Content-Length . Tenga en cuenta, sin embargo, que este no es necesariamente el caso.

Solo se puede descargar la cabecera usando una solicitud HEAD lugar de GET . Quizás el siguiente código ayude:

 HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://example.com/"); req.Method = "HEAD"; long len; using(HttpWebResponse resp = (HttpWebResponse)(req.GetResponse())) { len = resp.ContentLength; } 

Observe la propiedad para la longitud del contenido en el objeto HttpWebResponse ; no es necesario analizar manualmente el encabezado Content-Length .

 WebClient webClient = new WebClient(); webClient.OpenRead("http://stackoverflow.com/robots.txt"); long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]); Console.WriteLine((totalSizeBytes)); 

Tenga en cuenta que no todos los servidores aceptan solicitudes HTTP HEAD . Un enfoque alternativo para obtener el tamaño del archivo es realizar una llamada HTTP GET al servidor solicitando solo una parte del archivo para mantener la respuesta pequeña y recuperar el tamaño del archivo de los metadatos que se devuelven como parte del encabezado del contenido de la respuesta.

El estándar System.Net.Http.HttpClient se puede usar para lograr esto. El contenido parcial se solicita al establecer un rango de bytes en el encabezado del mensaje de solicitud como:

  request.Headers.Range = new RangeHeaderValue(startByte, endByte) 

El servidor responde con un mensaje que contiene el rango solicitado, así como el tamaño completo del archivo. Esta información se devuelve en el encabezado del contenido de la respuesta ( response.Content.Header ) con la clave “Content-Range”.

Aquí hay un ejemplo del rango de contenido en el encabezado del contenido del mensaje de respuesta:

  { "Key": "Content-Range", "Value": [ "bytes 0-15/2328372" ] } 

En este ejemplo, el valor del encabezado implica que la respuesta contiene bytes de 0 a 15 (es decir, 16 bytes en total) y el archivo tiene 2.328.372 bytes en su totalidad.

Aquí hay una implementación de ejemplo de este método:

 public static class HttpClientExtensions { public static async Task GetContentSizeAsync(this System.Net.Http.HttpClient client, string url) { using (var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url)) { // In order to keep the response as small as possible, set the requested byte range to [0,0] (ie, only the first byte) request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(from: 0, to: 0); using (var response = await client.SendAsync(request)) { response.EnsureSuccessStatusCode(); if (response.StatusCode != System.Net.HttpStatusCode.PartialContent) throw new System.Net.WebException($"expected partial content response ({System.Net.HttpStatusCode.PartialContent}), instead received: {response.StatusCode}"); var contentRange = response.Content.Headers.GetValues(@"Content-Range").Single(); var lengthString = System.Text.RegularExpressions.Regex.Match(contentRange, @"(?<=^bytes\s[0-9]+\-[0-9]+/)[0-9]+$").Value; return long.Parse(lengthString); } } } }