Come ottenere le dimensioni del file dalle intestazioni http


56

Desidero ottenere le dimensioni di un file http: /.../ prima di scaricarlo. Il file può essere una pagina Web, un'immagine o un file multimediale. Questo può essere fatto con le intestazioni HTTP? Come faccio a scaricare solo l'intestazione HTTP del file?

84

Sì, supponendo che il server HTTP che stai parlando con supporti/permette a questo:

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 
    } 
} 

Se si utilizza il metodo HEAD non è consentito, o l'intestazione Content-Length non è presente nella risposta del server, l'unico modo per determinare la dimensione del contenuto sul server è scaricarlo. Poiché questo non è particolarmente affidabile, la maggior parte dei server includerà queste informazioni.

+11

Se si utilizza l'opzione 'using', la elimina automaticamente. http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.110).aspx 16 apr. 132013-04-16 20:12:14

+2

Un'altra nota, se la si utilizza per file estremamente grandi, 'int' non è sufficiente, è necessario usare 'long ContentLength;' e 'long.TryParse (xxx)' per supportare più di un valore di ritorno di dimensione di 2.14 GB. 16 ott. 152015-10-16 04:27:33

  0

Non verrà abilitata la compressione http per eliminare la dimensione effettiva del file? 17 lug. 162016-07-17 23:06:01


25

Questo può essere fatto con le intestazioni HTTP?

Sì, questa è la strada da percorrere. Se viene fornita l'informazione, è nell'intestazione come Content-Length. Si noti, tuttavia, che questo non è necessariamente il caso.

È possibile scaricare solo l'intestazione utilizzando una richiesta HEAD anziché GET. Forse il seguente codice aiuta:

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

Avviso la proprietà per la lunghezza del contenuto sull'oggetto HttpWebResponse - non c'è bisogno di analizzare l'intestazione Content-Length manualmente.

  0

Non si rispetterà 'resp.ContentLength' in precedenza per fornire la lunghezza della risposta HEAD e non la lunghezza del file a cui si era interessati ad ottenere le dimensioni di? 19 apr. 112011-04-19 12:47:28

+1

@Adam No. La documentazione dice: "La proprietà ContentLength contiene il valore dell'intestazione Content-Length restituita con la risposta." 19 apr. 112011-04-19 12:57:06

+1

Corretto, grazie Konrad. 20 apr. 112011-04-20 12:15:05

  0

Assicurati di chiamare resp.Close() oppure puoi incontrare errori di timeout quando fai richieste multiple alla volta (la mia terza richiesta era scaduta in un ciclo foreach che era stato risolto chiudendo ogni risposta) 25 mar. 132013-03-25 20:56:43

+2

@Eric In effetti dovresti utilizzare un blocco 'Using' qui o implementare il pattern monouso per gestire esplicitamente la durata della risorsa. Chiamare manualmente 'Chiudi' non è sufficiente se non si assicura che * sempre * avvenga, anche in caso di errore. 25 mar. 132013-03-25 20:59:32

  0

@KonradRudolph Hai assolutamente ragione. Calling Close() ha corretto il mio bug mentre stavo testando questo, ma un blocco using è il modo corretto per farlo. Derp. 26 mar. 132013-03-26 00:59:02

  0

@KonradRudolph, FYI, 'ContentLength' restituisce un' long'. Non è un grosso problema, ma nel caso in cui si desidera risolvere il problema. 02 mag. 132013-05-02 00:14:08


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