如何在 iOS 7 中下载文件之前查找文件的大小?

Posted

技术标签:

【中文标题】如何在 iOS 7 中下载文件之前查找文件的大小?【英文标题】:How to find size of a file before downloading it in iOS 7? 【发布时间】:2013-10-11 10:09:11 【问题描述】:

想在 ios 7 中下载之前在某个服务器上查找文件的大小...我有一个 NSURLConnectionDelegate 方法,但在 iOS 4.3 之后它已被弃用

这是那个方法:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

【问题讨论】:

检查这个 Swift 4 解决方案:***.com/a/48584914/3161503 【参考方案1】:

使用 HEAD 方法发出请求。例如:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"HEAD"];

此请求与 GET 相同,但不会返回正文。然后调用

long long size = [response expectedContentLength];

带有 NSURLConnection 的完整示例(当然也适用于 NSURLSession):

NSURL *URL = [NSURL URLWithString:@"http://www.google.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:@"HEAD"];
NSHTTPURLResponse *response;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error: nil];
long long size = [response expectedContentLength];
NSLog(@"%lld",size);

这对于根据 Last-Modified 标头有条件地下载也很有用(假设服务器向您发送了该标头)。

if ([response respondsToSelector:@selector(allHeaderFields)]) 
    NSString *lastModifiedString = [[response allHeaderFields] objectForKey:@"Last-Modified"];

【讨论】:

【参考方案2】:

您应该改用NSURLConnectionDataDelegate 注意:DATADelegate

及其didReceiveResponse: 方法发送HEAD request 以获取标头:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

然后你可以通过@Port 的建议得到响应大小:

long long size = [response expectedContentLength];

【讨论】:

非常感谢,非常有帮助!! :) NSURLCONNECTIONDELEGATE 有很多方法被弃用,这些方法现在在 NSURLCONNECTIONDATADELEGATE 中呈现!【参考方案3】:

你可以使用这个方法,NSURLResponse 对象被传递给下面的委托方法:

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 


-(NSURLRequest *)connection:(NSURLConnection *)connection
        willSendRequest:(NSURLRequest *)request
       redirectResponse:(NSURLResponse *)response 

像这样尝试..

long long size = [response expectedContentLength];

【讨论】:

它也被弃用了。 --connection:needNewBodyStream--connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: 必需的方法在iOS 3.0 到iOS 4.3 中可用--connection:didReceiveData: 必需的方法在iOS 2.0 到iOS 4.3 中可用--connection:didReceiveResponse: 必需方法 适用于 iOS 2.0 至 iOS 4.3 – connection:willCacheResponse: required 方法 适用于 iOS 2.0 至 iOS 4.3 – connection:willSendRequest:redirectResponse: required 方法 适用于 iOS 2.0 至 iOS 4.3 – connectionDidFinishLoading: 所需方法 适用于 iOS 2.0 至 iOS 4.3 【参考方案4】:

对于 Swift,请使用这些步骤,

第 1 步:使用 NSURLConnectionDataDelegate

class ViewController: UIViewController,NSURLConnectionDataDelegate 

第 2 步:为连接创建 请求

var request:NSMutableURLRequest = NSMutableURLRequest(URL: NSURL(string: "http://www.twitter.com")!)

// Use **HEAD** request to get http header information.

request.HTTPMethod = "HEAD"

第 3 步:创建连接。

var connection:NSURLConnection = NSURLConnection(request: request, delegate: self)!

第四步:使用NSURLConnectionDataDelegate

delegate方法
func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)

    var size = response.expectedContentLength
    println("size : \(size)")

这里是完整的代码...

import UIKit

class ViewController: UIViewController,NSURLConnectionDataDelegate 

override func viewDidLoad() 
    super.viewDidLoad()


    var request:NSMutableURLRequest = NSMutableURLRequest(URL: NSURL(string: "http://www.twitter.com")!)
    request.HTTPMethod = "HEAD"

    var connection:NSURLConnection = NSURLConnection(request: request, delegate: self)!



func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)

    var size = response.expectedContentLength
    println("size : \(size)")


【讨论】:

是以字节为单位的大小? @RayKing , So you can assume byte unit on most modern platform where a byte is 8 bits long. 见这里:***.com/a/31389001/3411787【参考方案5】:

试试这个会有帮助。 . . . .

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
                                                                      *)response

    NSHTTPURLResponse * pHttpUrlResponse = (NSHTTPURLResponse *) response;

    if ([response respondsToSelector:@selector(allHeaderFields)])
    
        NSString * fileLength = [NSString stringWithFormat:@"%lld",[pHttpUrlResponse expectedContentLength]];
        

编码愉快 :)

【讨论】:

这是我在问题中列出的已弃用方法。【参考方案6】:

同样使用URlSession,您无需下载实际数据即可获得这样的文件大小:

func getPdfSize(for url: URL) 
    var request = URLRequest(url: url)
    request.httpMethod = "HEAD"

    URLSession.shared.dataTask(with: request)  [weak self] (_, response, _) in
        if let response = response 
            let size = response.expectedContentLength
            DispatchQueue.main.async 
                self?.fileSizeLabel.text = ByteCountFormatter.string(fromByteCount: size, countStyle: .file)
            
        
    .resume()

请注意,您还可以使用原生 iOS ByteCountFormatter 将字节数格式化为可读字符串。

Swift 5 中的代码

【讨论】:

【参考方案7】:

试试这个,

NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:URL error:&attributesError];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
long long fileSize = [fileSizeNumber longLongValue];

:)

【讨论】:

这是已经下载的文件,不适用于网络文件。 好的...为此我认为你必须使用 ftp。

以上是关于如何在 iOS 7 中下载文件之前查找文件的大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在CMD命令中下载文件

如何在 Puppeteer 中下载文件之前更改文件名?

如何在 wkwebview 中下载文件

在iOS中下载文件[重复]

如何使用 selenium 在点击事件中下载文件?

如何使用 webview 组件在 App 中下载文件?