Question

Je souhaite obtenir la taille d’un fichier http: /.../ avant de le télécharger. Le fichier peut être une page Web, une image ou un fichier multimédia. Cela peut-il être fait avec des en-têtes HTTP? Comment télécharger uniquement l'en-tête HTTP du fichier?

Était-ce utile?

La solution

Oui, en supposant que le serveur HTTP auquel vous parlez prend en charge / autorise ceci:

public long GetFileSize(string url)
{
    long result = -1;

    System.Net.WebRequest req = System.Net.WebRequest.Create(url);
    req.Method = "HEAD";
    using (System.Net.WebResponse resp = req.GetResponse())
    {
        if (long.TryParse(resp.Headers.Get("Content-Length"), out long ContentLength))
        {
            result = ContentLength;
        }
    }

    return result;
}

Si l'utilisation de la méthode HEAD n'est pas autorisée ou si l'en-tête Content-Length n'est pas présent dans la réponse du serveur, le seul moyen de déterminer la taille du contenu du serveur consiste à le télécharger. Comme cela n’est pas particulièrement fiable, la plupart des serveurs incluront ces informations.

Autres conseils

  

Cela peut-il être fait avec des en-têtes HTTP?

Oui, c'est la voie à suivre. Si les informations sont fournies, elles figurent dans l'en-tête sous la forme Content-Length . Notez cependant que ce n'est pas nécessairement le cas.

Le téléchargement de l'en-tête uniquement peut être effectué à l'aide d'une requête HEAD au lieu de GET . Peut-être que le code suivant peut aider:

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

Notez la propriété de la longueur du contenu sur l'objet HttpWebResponse & # 8211; & nbsp; inutile d'analyser manuellement l'en-tête Content-Length .

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

Notez que tous les serveurs n'acceptent pas les requêtes HTTP HEAD . Une autre solution pour obtenir la taille du fichier consiste à appeler le serveur HTTP GET , lui demandant de ne conserver qu’une partie du fichier afin de conserver une réponse réduite et d’extraire la taille du fichier à partir des métadonnées renvoyées. de l'en-tête de contenu de la réponse.

Le standard System.Net.Http.HttpClient peut être utilisé à cette fin. Le contenu partiel est demandé en définissant une plage d'octets sur l'en-tête du message de requête comme suit:

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

Le serveur répond avec un message contenant la plage demandée ainsi que la taille totale du fichier. Ces informations sont renvoyées dans l'en-tête du contenu de la réponse ( response.Content.Header ) avec la clé "Content-Range".

Voici un exemple de la plage de contenu dans l'en-tête de contenu du message de réponse:

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

Dans cet exemple, la valeur de l'en-tête implique que la réponse contient les octets 0 à 15 (soit un total de 16 octets) et que le fichier contient 2 328 372 octets.

Voici un exemple d'implémentation de cette méthode:

public static class HttpClientExtensions
{
    public static async Task<long> 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] (i.e., 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(<*>quot;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]+<*>quot;).Value;
                return long.Parse(lengthString);
            }
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top