能否通过WebResponse获取磁盘文件大小?若不可行,该如何获取?
关于通过WebResponse获取文件大小的问题解答
嘿,我来帮你理清这个问题!
首先直接回答你的第一个问题:是可以通过WebResponse获取文件大小的,但得注意一些前提和细节,下面给你详细说明:
1. 用WebResponse获取文件大小的方法
WebResponse对象有一个ContentLength属性,它对应HTTP响应头里的Content-Length字段,只要服务器在响应中返回了这个字段,你就能直接拿到文件的字节大小。
不过有个关键限制:如果服务器采用分块传输编码(响应头里有Transfer-Encoding: chunked),ContentLength会返回-1,这时候就没法通过这个属性直接获取大小了。
2. 更高效的获取方式:使用HEAD请求
如果你只是想获取文件大小,完全没必要像你现在的代码那样下载整个文件——改用HEAD请求会更省带宽、更快,因为HEAD请求只会返回响应头,不会返回文件内容。
给你改个示例代码:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(finalUrl); request.AllowAutoRedirect = true; request.KeepAlive = false; request.ProtocolVersion = HttpVersion.Version10; request.ServicePoint.ConnectionLimit = 24; request.Method = "HEAD"; // 切换为HEAD请求 long fileSize = -1; string contentType = string.Empty; using (WebResponse webResponse = request.GetResponse()) { contentType = webResponse.ContentType; fileSize = webResponse.ContentLength; } if (fileSize != -1) { Console.WriteLine($"文件大小:{fileSize} 字节"); } else { Console.WriteLine("无法通过响应头获取文件大小,服务器可能使用了分块传输"); }
3. 如果你需要下载文件同时获取大小
如果你的需求是既要下载文件,又要获取大小,可以在原代码里直接加入ContentLength的获取逻辑,同时处理它为-1的情况(这时候就用下载后的实际数据长度来判断):
修改后的代码如下:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(finalUrl); request.AllowAutoRedirect = true; request.KeepAlive = false; request.ProtocolVersion = HttpVersion.Version10; request.ServicePoint.ConnectionLimit = 24; //request.Method = "HEAD"; var contentType = string.Empty; long fileSizeFromHeader = -1; using (WebResponse webResponse = request.GetResponse()) { contentType = webResponse.ContentType; fileSizeFromHeader = webResponse.ContentLength; // 从响应头获取大小 using (Stream stream = webResponse.GetResponseStream()) { using (MemoryStream memoryStream = new MemoryStream()) { Byte[] buffer = new Byte[1024]; Int32 bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { memoryStream.Write(buffer, 0, bytesRead); } documentFile.Data = memoryStream.ToArray(); } } } // 输出文件大小信息 if (fileSizeFromHeader != -1) { Console.WriteLine($"响应头返回的文件大小:{fileSizeFromHeader} 字节"); } // 如果响应头拿不到,就用实际下载的数据长度 Console.WriteLine($"实际下载的文件大小:{documentFile.Data.Length} 字节");
总结一下
- 要获取文件大小,优先用
HEAD请求+ContentLength属性,高效又省资源; - 如果必须下载文件,也可以在下载前通过
WebResponse.ContentLength尝试获取大小,失败的话就用下载后的数据长度来得到实际大小。
内容的提问来源于stack exchange,提问作者Gonzalo
相关产品推荐
相关产品推荐

