Swift - получить размер файла по URL-адресу

Я использую 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)")
        }

    }

Я получаю сообщение об ошибке, этот файл не существует, где средство выбора документов сохраняет файл и как получить его атрибуты.


person yasser h    schedule 05.05.2017    source источник
comment
Возможно, это то, что вы ищете: stackoverflow.com/questions/19315533/   -  person Sivajee Battina    schedule 05.05.2017
comment
Спасибо, ссылка мне помогла.   -  person yasser h    schedule 05.05.2017
comment
Добро пожаловать ;-)   -  person Sivajee Battina    schedule 05.05.2017


Ответы (5)


Прежде всего, в файловой системе вы получаете путь URL-адреса со свойством path.

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)")
}
person vadian    schedule 05.05.2017
comment
в iOS 11 я получаю сообщение об ошибке Error Domain=NSCocoaErrorDomain Code=257 Файл не может быть открыт, так как у вас нет разрешения на его просмотр. - person Sneha; 27.11.2017
comment
должен ли этот метод работать для элемента MPMedia, выбранного MPMediaPickerController? - person Awais Fayyaz; 08.02.2019
comment
@AwaisFayyaz Если вы можете получить URL-адрес актива, то да. - person vadian; 08.02.2019
comment
@vadian Я получил URL-адрес ресурса выбранного элемента. Это выглядит так: ipod-library://item/item.mp3?id=9046838634016568305 Когда я попробовал ваш код, размер файла равен нулю. Любые идеи? - person Awais Fayyaz; 08.02.2019
comment
@AwaisFayyaz Я не знаком с этой схемой. Чтобы получить размер, вам нужен file:// URL в файловой системе. - person vadian; 08.02.2019

Свифт 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
}
person Ahmed Lotfy    schedule 08.11.2017

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
    }
person Gurjinder Singh    schedule 20.06.2018
comment
Слишком много мест, где этот код может дать сбой. И самое главное не будет работать на файлах › 2Gb - person Evgen Bodunov; 25.12.2019
comment
@EvgenBodunov Почему это не работает, когда размер файла превышает 2 ГБ? - person Kimi Chiu; 26.05.2020

С последней версией 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)
}
person sinner    schedule 24.07.2017

person    schedule
comment
Пожалуйста, добавьте комментарий, чтобы объяснить, что именно делает это расширение. - person Roman; 03.06.2020