【问题标题】:Swift - Get file size from urlSwift - 从 url 获取文件大小
【发布时间】:2017-10-03 11:35:41
【问题描述】:

我正在使用 documentPicker 获取任何文档的 url 路径,然后上传到数据库。我正在选择文件(pdf、txt ..),上传正常,但我想限制文件的大小。

 public func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {

        self.file = url //url
        self.path = String(describing: self.file!) // url to string
        self.upload = true //set upload to true
        self.attachBtn.setImage(UIImage(named: "attachFilled"), for: .normal)//set image
        self.attachBtn.tintColor = UIColor.black //set color tint
        sendbtn.tintColor = UIColor.white //


        do
        {
            let fileDictionary = try FileManager.default.attributesOfItem(atPath: self.path!)
            let fileSize = fileDictionary[FileAttributeKey.size]
            print ("\(fileSize)")
        } 
        catch{
            print("Error: \(error)")
        }

    }

我收到错误消息,此文件不存在,文档选择器将文件保存在哪里以及如何获取他的属性。

【问题讨论】:

标签: ios swift filesize uidocumentpickervc


【解决方案1】:

首先,在文件系统中,您可以使用path 属性获取 URL 的路径。

self.path = url.path

但你根本不需要那个。您可以直接从 URL 中检索文件大小:

self.path = String(describing: self.file!) // url to string

do {
    let resources = try url.resourceValues(forKeys:[.fileSizeKey])
    let fileSize = resources.fileSize!
    print ("\(fileSize)")
} catch {
    print("Error: \(error)")
}

【讨论】:

  • 在 iOS 11 中,我收到错误 Error Domain=NSCocoaErrorDomain Code=257 "该文件无法打开,因为您无权查看它。"
  • 这种技术是否适用于 MPMediaPickerController 选择的 MPMedia 项目?
  • @AwaisFayyaz 如果您可以获取资产的 URL,那么可以。
  • @vadian 我得到了所选项目的assetURL。这看起来像ipod-library://item/item.mp3?id=9046838634016568305 当我尝试你的代码时,fileSize 为零。有什么想法吗?
  • @AwaisFayyaz 我不熟悉这个方案。要获得大小,您需要文件系统中的file:// URL。
【解决方案2】:

斯威夫特 4:

func sizePerMB(url: URL?) -> Double {
    guard let filePath = url?.path else {
        return 0.0
    }
    do {
        let attribute = try FileManager.default.attributesOfItem(atPath: filePath)
        if let size = attribute[FileAttributeKey.size] as? NSNumber {
            return size.doubleValue / 1000000.0
        }
    } catch {
        print("Error: \(error)")
    }
    return 0.0
}

【讨论】:

    【解决方案3】:

    Swift 4.1 和 5

    func fileSize(forURL url: Any) -> Double {
            var fileURL: URL?
            var fileSize: Double = 0.0
            if (url is URL) || (url is String)
            {
                if (url is URL) {
                    fileURL = url as? URL
                }
                else {
                    fileURL = URL(fileURLWithPath: url as! String)
                }
                var fileSizeValue = 0.0
                try? fileSizeValue = (fileURL?.resourceValues(forKeys: [URLResourceKey.fileSizeKey]).allValues.first?.value as! Double?)!
                if fileSizeValue > 0.0 {
                    fileSize = (Double(fileSizeValue) / (1024 * 1024))
                }
            }
            return fileSize
        }
    

    【讨论】:

    • 此代码可能失败的地方太多。最重要的是,它不适用于 > 2Gb 的文件
    • @EvgenBodunov 为什么文件大小超过2GB就不行了?
    【解决方案4】:

    使用最新版本的 swift 可以很容易地使用字节计数器格式化程序计算文件大小:

    var fileSizeValue: UInt64 = 0
            
    do {
        
        let fileAttribute: [FileAttributeKey : Any] = try FileManager.default.attributesOfItem(atPath: url.path)
        
        if let fileNumberSize: NSNumber = fileAttribute[FileAttributeKey.size] as? NSNumber {
            fileSizeValue = UInt64(fileNumberSize)
            
            let byteCountFormatter: ByteCountFormatter = ByteCountFormatter()
            byteCountFormatter.countStyle = ByteCountFormatter.CountStyle.file
            
            byteCountFormatter.allowedUnits = ByteCountFormatter.Units.useBytes
            print(byteCountFormatter.string(fromByteCount: Int64(fileSizeValue)))
    
            byteCountFormatter.allowedUnits = ByteCountFormatter.Units.useKB
            print(byteCountFormatter.string(fromByteCount: Int64(fileSizeValue)))
    
            byteCountFormatter.allowedUnits = ByteCountFormatter.Units.useMB
            print(byteCountFormatter.string(fromByteCount: Int64(fileSizeValue)))
        
        }
        
    } catch {
        print(error.localizedDescription)
    }
    

    【讨论】:

      【解决方案5】:
      extension URL {
          func fileSize() -> Double {
              var fileSize: Double = 0.0
              var fileSizeValue = 0.0
              try? fileSizeValue = (self.resourceValues(forKeys: [URLResourceKey.fileSizeKey]).allValues.first?.value as! Double?)!
              if fileSizeValue > 0.0 {
                  fileSize = (Double(fileSizeValue) / (1024 * 1024))
              }
              return fileSize
          }
      }
      

      【讨论】:

      • 请添加评论以解释此扩展的具体作用。
      猜你喜欢
      • 2018-05-08
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      • 2019-02-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多