İPhone / iPad cihazındaki toplam kullanılabilir / boş disk alanı nasıl tespit edilir?


148

İPhone / iPad aygıtındaki kullanılabilir / boş disk alanını programlı olarak saptamanın daha iyi bir yolunu arıyorum.
Şu anda disk alanını algılamak için NSFileManager kullanıyorum. Benim için işi yapan kodun pasajı aşağıdadır:

-(unsigned)getFreeDiskspacePrivate {
NSDictionary *atDict = [[NSFileManager defaultManager] attributesOfFileSystemForPath:@"/" error:NULL];
unsigned freeSpace = [[atDict objectForKey:NSFileSystemFreeSize] unsignedIntValue];
NSLog(@"%s - Free Diskspace: %u bytes - %u MiB", __PRETTY_FUNCTION__, freeSpace, (freeSpace/1024)/1024);

return freeSpace;
}


Yukarıdaki kod parçasında haklı mıyım? veya toplam kullanılabilir / boş disk alanını bilmenin daha iyi bir yolu var mı?
Uygulamamızın düşük disk alanı senaryosunda senkronizasyon gerçekleştirmesini engellememiz gerektiğinden, toplam boş disk alanını tespit etmeliyim.



1
Görünüşe göre sorusunda kullandığı kod, verdiğiniz bağlantıdaki koddan daha iyi ("/" altındaki tüm alt dizinlerde
gezinmek

Bağlantı için teşekkürler Mikhail. Ancak yalnızca belirli bir klasör değil, iPhone / iPad cihazında toplam kullanılabilir / boş disk alanı arıyorum. Örneğin, 32GB bir iPhone'da toplam kullanılabilir / boş boyut 28GB ise, bunu programlı olarak algılayabilmeliyim.
Code.Decode

Umarım bu bağlantı yardımcı olur: jayprakashdubey.blogspot.in/2014/07/…
Jayprakash Dubey

Yanıtlar:


152

GÜNCELLEME : Bu yanıtın üzerinden çok zaman geçtiği ve yeni yöntemler / API'ler eklendiğinden, lütfen Swift vb. İçin aşağıdaki güncellenmiş yanıtları kontrol edin; Onları kendim kullanmadığım için onlara kefil olamam.

Orijinal cevap : Aşağıdaki çözümü benim için çalışıyor buldum:

-(uint64_t)getFreeDiskspace {
    uint64_t totalSpace = 0;
    uint64_t totalFreeSpace = 0;
    NSError *error = nil;  
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];  

    if (dictionary) {  
        NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];  
        NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
        totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
        totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
        NSLog(@"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
    } else {  
        NSLog(@"Error Obtaining System Memory Info: Domain = %@, Code = %ld", [error domain], (long)[error code]);
    }  

    return totalFreeSpace;
}

Bana, aygıt makineye bağlandığında iTunes'un görüntülediği boyutu döndürüyor.


4
Şamandıraya dönüştürmek, yaklaşık 2 GB'ın üzerinde hatalı sonuçlar verebilir. Gerçekten büyük dosya boyutlarıyla uğraşmanız gerekiyorsa, bunun yerine çift veya uzun bir çift kullanın.
Ash

Ash'in işaret ettiği gibi, bu yöntemin yanlış bir sonucu var. 64GB'lık iPad 2'mde +0.25 GB ile başarısız oluyor ... David H tarafından yayınlanan aşağıdaki yöntem, uint64_t vars kullanırken doğru sonuca sahip.
Leandro Alves

3
Kod pasajı, aşağıda gösterildiği gibi @David H'den gelen önerileri yansıtacak şekilde düzenlenmiştir.
Code.Decode

4
+200 MB sorun değil. Ayarlarda "0 bayt" kullanılabilir alanım var. Uygulamama girdiğimde ve kullandığımda, bu yöntem 150mb boş alan hakkında rapor veriyor. Sonra bu kalan alanı dolduruyorum ve ancak o zaman uygulama çöküyor. Bu nedenle, bu yöntemin size Ayarlar'da gördüğünüzden daha doğru bilgi verdiğini söyleyebilirim.
ancajic

4
Neden kimse NSUIntegerbunun gibi şeyler yerine kullanmıyor uint64_t? C ++ veya C değil, Obj-C yazıyoruz NSUInteger şimdi size imzasız 64 bitlik bir tamsayı verecek, ancak işler değişirse Apple'ın bu Makroyu güncelleyeceğini hayal ediyorum (bir noktada 128 bit diyelim, gerçek oluyor)
Goles

60

Unsigned long kullanılarak revize edilmiş kaynak:

- (uint64_t)freeDiskspace
{
    uint64_t totalSpace = 0;
    uint64_t totalFreeSpace = 0;

    __autoreleasing NSError *error = nil;  
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
    NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];  

    if (dictionary) {  
        NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];  
        NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
        totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
        totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
        NSLog(@"Memory Capacity of %llu MiB with %llu MiB Free memory available.", ((totalSpace/1024ll)/1024ll), ((totalFreeSpace/1024ll)/1024ll));
    } else {  
        NSLog(@"Error Obtaining System Memory Info: Domain = %@, Code = %d", [error domain], [error code]);  
    }  

    return totalFreeSpace;
}

DÜZENLEME: Görünüşe göre birisi bu kodu 'unsigned long long' yerine 'uint64_t' kullanacak şekilde düzenledi. Öngörülebilir gelecekte bu gayet iyi olsa da, bunlar aynı değil. 'uint64_t' 64 bittir ve her zaman böyle olacaktır. 10 yılda 'işaretsiz uzun uzun' 128 olabilir. Bu küçük bir nokta ama neden unsignedLongLong kullandım.


Yeni otomatik sayma sistemiyle ilgili deneyimim yok ama __autorelasing ne için? Normalde döndürülen NSError'ı otomatik olarak serbest bırakmanıza gerek yoktur
Reverend


3
iOS 5.1 çalıştıran iPod Touch 4. Nesil cihazımda NSFileSystemFreeSize hala ~ 200 MByte fazla olduğunu bildiriyor. Hata ayıklayıcıda tüm NSDictionary içeriğini yazdırıyorum ... NSFileSystemSize doğru olsa da ... bu sorun için çözümü olan var mı?
Zennichimaro

@Zennichimaro: Sorununuzu çözdünüz mü? Ben de aynı sorunla karşı karşıyayım, iPad'de boş alanı kontrol ettiğimde fazladan 0,2 GB alıyorum. iPad 24.1 GB kullanılabilir alan gösteriyor ancak kodda 24.3 GB gösteriyor.
Sudheer Kumar Palchuri

1
@Diejmon NSNumber'dan bu türden bir tam boyut isteyemezsiniz. Bu yüzden bu tür şeyler için bit boyutu bilinen bir birimi tercih ediyorum. Teknik olarak ifadenize katılıyorum, ancak NSInteger ve biçim dizelerini kullanmak için zaten yeterince uyarı aldım! 64 bit kesinlikle benim ve sizin hayatımda yeterli olacak.
David H.

35

Swift kullanarak kullanılabilir / kullanılan hafızayı elde etmek için bir sınıf yazdım. Demo: https://github.com/thanhcuong1990/swift-disk-status
Swift 4 güncellendi.

import UIKit

class DiskStatus {

    //MARK: Formatter MB only
    class func MBFormatter(_ bytes: Int64) -> String {
        let formatter = ByteCountFormatter()
        formatter.allowedUnits = ByteCountFormatter.Units.useMB
        formatter.countStyle = ByteCountFormatter.CountStyle.decimal
        formatter.includesUnit = false
        return formatter.string(fromByteCount: bytes) as String
    }


    //MARK: Get String Value
    class var totalDiskSpace:String {
        get {
            return ByteCountFormatter.string(fromByteCount: totalDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.file)
        }
    }

    class var freeDiskSpace:String {
        get {
            return ByteCountFormatter.string(fromByteCount: freeDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.file)
        }
    }

    class var usedDiskSpace:String {
        get {
            return ByteCountFormatter.string(fromByteCount: usedDiskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.file)
        }
    }


    //MARK: Get raw value
    class var totalDiskSpaceInBytes:Int64 {
        get {
            do {
                let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String)
                let space = (systemAttributes[FileAttributeKey.systemSize] as? NSNumber)?.int64Value
                return space!
            } catch {
                return 0
            }
        }
    }

    class var freeDiskSpaceInBytes:Int64 {
        get {
            do {
                let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String)
                let freeSpace = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value
                return freeSpace!
            } catch {
                return 0
            }
        }
    }

    class var usedDiskSpaceInBytes:Int64 {
        get {
            let usedSpace = totalDiskSpaceInBytes - freeDiskSpaceInBytes
            return usedSpace
        }
    }

}

Demo

Swift ile disk alanı durumunu öğrenin


MBFormatter'ın neden orada olduğuna dair bir fikriniz var mı? Hiçbir yerde kullanılmıyor.
pronebird

MBFormatter, herhangi bir değeri MB değerine dönüştürmek için bir işlevdir. Demo proje için kullanmıyorum. Ama başka bir projeye ihtiyacım var.
Cuong Lam

1
Bu, bir FileManager uzantısı eklemek harika.
Leon

2
iTunes, 18.99 GB ücretsiz gösteriyor ancak açıklanan yöntemleri kullandığımda 13.41 GB alıyorum. Neyi özlediğimi bilen var mı?
Vitalii Boiarskyi

1
@CuongLam Paket açma hataları atılmaz ve do / catch tarafından yakalanmaz. Hataların doğru işlenmesi için örnek kaynak kodu yazılmalıdır. stackoverflow.com/questions/34628999/…
SafeFastExpressive

26

Boyutla biçimlendirilmiş dizeye ihtiyacınız varsa GitHub'daki güzel kitaplığa göz atabilirsiniz :

#define MB (1024*1024)
#define GB (MB*1024)

@implementation ALDisk

#pragma mark - Formatter

+ (NSString *)memoryFormatter:(long long)diskSpace {
    NSString *formatted;
    double bytes = 1.0 * diskSpace;
    double megabytes = bytes / MB;
    double gigabytes = bytes / GB;
    if (gigabytes >= 1.0)
        formatted = [NSString stringWithFormat:@"%.2f GB", gigabytes];
    else if (megabytes >= 1.0)
        formatted = [NSString stringWithFormat:@"%.2f MB", megabytes];
    else
        formatted = [NSString stringWithFormat:@"%.2f bytes", bytes];

    return formatted;
}

#pragma mark - Methods

+ (NSString *)totalDiskSpace {
    long long space = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemSize] longLongValue];
    return [self memoryFormatter:space];
}

+ (NSString *)freeDiskSpace {
    long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
    return [self memoryFormatter:freeSpace];
}

+ (NSString *)usedDiskSpace {
    return [self memoryFormatter:[self usedDiskSpaceInBytes]];
}

+ (CGFloat)totalDiskSpaceInBytes {
    long long space = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemSize] longLongValue];
    return space;
}

+ (CGFloat)freeDiskSpaceInBytes {
    long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
    return freeSpace;
}

+ (CGFloat)usedDiskSpaceInBytes {
    long long usedSpace = [self totalDiskSpaceInBytes] - [self freeDiskSpaceInBytes];
    return usedSpace;
}

2
Biçimlendirmek için NSBytCounterFormatter
Daniel Barden

Bu hala aynı + 200MB hatasına yatkın: stackoverflow.com/questions/9270027/…
Paulius Liekis

13

'İşaretsiz' kullanmayın, yalnızca 32 bit olan 4 GB'yi aşacaktır, bu tipik iPad / iPhone boş alanından daha azdır. Unsigned long (veya uint64_t) kullanın ve unsignedLongLongValue kullanarak NSNumber içindeki değeri 64-bit int olarak alın.


3
Bu bir bahşişten daha iyi - "Bu Kanun" :-) Dediği gibi, orijinal kod tamamen yanlış.
David H

13

Kalan boş alanı Swift kullanarak almak istiyorsanız biraz farklıdır. AttributesOfItemAtPath () yerine attributesOfFileSystemForPath () kullanmanız gerekir:

func deviceRemainingFreeSpaceInBytes() -> Int64? {
    let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
    var attributes: [String: AnyObject]
    do {
        attributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last! as String)
        let freeSize = attributes[NSFileSystemFreeSize] as? NSNumber
        if (freeSize != nil) {
            return freeSize?.longLongValue
        } else {
            return nil
        }
    } catch {
        return nil
    }
}

Düzenleme: Swift 1.0 için güncellendi
Düzenleme 2: Güvenlik için Martin R'nin cevabı kullanılarak güncellendi .
Düzenleme 3: Swift 2.0 için güncellendi ( dgellow tarafından )


Bu yanıtı kullanmaya çalışıyordum, ancak GM altında derlenmeyecek ([NSObject: AnyObject]? 'Alt simge' adlı bir üyeye sahip değil). Sanırım bu, burada dile getirilen meseleden kaynaklanıyor ancak bu cevabı bu bağlamda nasıl çalıştıracağımı anlamıyorum. Herhangi bir yardım çok takdir edildi.
Bryan Hanson

Şimdi Swift 1.0'da çalışmak için cevabı güncelledim. AttributesOfFileSystemForPath [NSObject: AnyObject] döndürdüğü için? NSDictionary çevirmeniz mi gerekiyor? sıfır olabileceğinden ve ardından alt simge için sözlüğün sarmalını kaldırın. (Bu biraz güvensiz, bu yüzden zamanım olduğunda daha güvenli bir çözümle cevabı biraz daha güncelleyeceğim.)
RubenSandwich

Güncelleme için teşekkürler. Görünüşe göre, cevabınızdan yaklaşık bir saat önce devam ettim ve konuyu burada yeni bir soru olarak formüle ettim . Şimdi orada bir cevap var, ancak bu opsiyonel işlemlerle başa çıkma yöntemi benim için biraz opak olduğundan, sizin için uygun olan başka bir yaklaşım görmeyi çok isterim. Kardeşin Rachel'a saygılarımı ilet.
Bryan Hanson

Bryan, güvenlik ve netliğin iyi bir karışımı olduğu için cevaplanan sorunuza ilk cevabı öneririm. Bundan daha iyi bir cevap verebileceğime emin değilim. Opsiyonlar ilk başta kafa karıştırıcı olabilir , opsiyonel olarak Swift kılavuzları bölümünü okumanızı şiddetle tavsiye ederim , oldukça iyidir.
RubenSandwich

Çok minnettarım, bu kılavuza tekrar bakacağım ve bazı iyi SO soruları da buldum. Bryan
Bryan Hanson

9

İşte cevabım ve neden daha iyi?

Cevap (Swift):

func remainingDiskSpaceOnThisDevice() -> String {
    var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")
    if let attributes = try? FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory()),
        let freeSpaceSize = attributes[FileAttributeKey.systemFreeSize] as? Int64 {
        remainingSpace = ByteCountFormatter.string(fromByteCount: freeSpaceSize, countStyle: .file)
    }
    return remainingSpace
}

Cevap (Amaç-C):

- (NSString *)calculateRemainingDiskSpaceOnThisDevice
{
    NSString *remainingSpace = NSLocalizedString(@"Unknown", @"The remaining free disk space on this device is unknown.");
    NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
    if (dictionary) {
        long long freeSpaceSize = [[dictionary objectForKey:NSFileSystemFreeSize] longLongValue];
        remainingSpace = [NSByteCountFormatter stringFromByteCount:freeSpaceSize countStyle:NSByteCountFormatterCountStyleFile];
    }
    return remainingSpace;
}

Neden daha iyi:

  • Cocoa'nın yerleşik kitaplığını kullanır NSByteCountFormatter, yani bayttan gigabayta kadar çılgın manuel hesaplamalara gerek yoktur. Apple bunu sizin için yapıyor!
  • Kolayca çevrilebilir: NSByteCountFormatterbunu sizin için yapar. Örneğin, aygıtın dili İngilizce olarak ayarlandığında, dizi 248,8 MB okuyacaktır, ancak Fransızca olarak ayarlandığında 248,8 Mo okuyacaktır, vb. Diğer diller için.
  • Bir hata durumunda varsayılan bir değer verilir.

1
@JuanBoero Yayınlanan Swift 3.1 (nihayet)!
ChrisJF

9

İOS11'de kullanılabilir diskte kullanılabilir boyut elde etmek için yeni bir doğru API ile güncelleme yapın. Yeni API kaynak anahtarının açıklaması:

#if os(OSX) || os(iOS)
/// Total available capacity in bytes for "Important" resources, including space expected to be cleared by purging non-essential and cached resources. "Important" means something that the user or application clearly expects to be present on the local system, but is ultimately replaceable. This would include items that the user has explicitly requested via the UI, and resources that an application requires in order to provide functionality.
/// Examples: A video that the user has explicitly requested to watch but has not yet finished watching or an audio file that the user has requested to download.
/// This value should not be used in determining if there is room for an irreplaceable resource. In the case of irreplaceable resources, always attempt to save the resource regardless of available capacity and handle failure as gracefully as possible.
@available(OSX 10.13, iOS 11.0, *) @available(tvOS, unavailable) @available(watchOS, unavailable)
public var volumeAvailableCapacityFor Usage: Int64? { return _get(.volumeAvailableCapacityForImportantUsageKey) }
#endif

" FileAttributeKey.systemFreeSize " anahtarından ve " URLResourceKey.volumeAvailableCapacityForImportantUsageKey " anahtarından gelen sonuçları karşılaştırdım ve " volumeAvailableCapacityForImportantUsageKey " biçiminde döndürülen sonuçların UI'de gösterilen kullanılabilir depolama alanıyla tam olarak eşleştiğini buldum . Kullanılabilir boş disk alanı karşılaştırması İşte hızlı uygulama:

class var freeDiskSpaceInBytesImportant:Int64 {
    get {
        do {
            return try URL(fileURLWithPath: NSHomeDirectory() as String).resourceValues(forKeys: [URLResourceKey.volumeAvailableCapacityForImportantUsageKey]).volumeAvailableCapacityForImportantUsage!
        } catch {
            return 0
        }
    }
}

Ekran görüntünüzde "fırsatçı kullanım" nereden geliyor?
rshev

Buldum volumeAvailableCapacityForOpportunisticUsageKey,.
rshev

Evet rshev, volumeAvailableCapacityForOpportunisticUsageKey ekran görüntüsümde "" fırsatçı kullanım "alıyor
Evilisn Jiang

NSHomeDirectory()veya ile sorgulamalıyım kullanılabilir depolama boyutunu görmek için NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true). Bu ikisini kullanarak herhangi bir fark var mı?
Suryakant Sharma

7

Önemli açıklama (en azından benim için). İPod'umu Mac'ime bağlarsam, bu iTunes Uygulaması tarafından gösterilen bilgidir.

iTunes uygulamasından iPod bellek bilgileri

Yukarıdaki kodu kullandığımda:

long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil]
                            objectForKey:NSFileSystemFreeSize] longLongValue];

NSString *free1 = [NSByteCountFormatter stringFromByteCount:freeSpace countStyle:NSByteCountFormatterCountStyleFile];

[label1 setText:free1];

NSString *free2 = [NSByteCountFormatter stringFromByteCount:freeSpace countStyle:NSByteCountFormatterCountStyleBinary];

[label2 setText:free2];

CountStyle NSByteCountFormatterCountStyleFile bana göster: 17,41 GB

CountStyle NSByteCountFormatterCountStyleBinary bana göster: 16,22 GB

16,22 GB ( NSByteCountFormatterCountStyleBinary ) Tam olarak iPod'umu Mac'ime bağladığımda iTunes Uygulamasının bana gösterdiği sayıdır.


belki Dosya yalnızca MAC dosyaları içindir, iOS için değil?
João Nunes

1000 (KB sonra MB sonra GB) ile 1024 ile çarpılan aynı bayt miktarıdır.
Jim75

7

Swift 4'ü kullanarak başka bir çözüm bulabilirsiniz ve extensionbu size iyi bir seçenek sunar.

İşte UIDeviceuzantı.

extension UIDevice {

    func totalDiskSpaceInBytes() -> Int64 {
        do {
            guard let totalDiskSpaceInBytes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemSize] as? Int64 else {
                return 0
            }
            return totalDiskSpaceInBytes
        } catch {
            return 0
        }
    }

    func freeDiskSpaceInBytes() -> Int64 {
        do {
            guard let totalDiskSpaceInBytes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemFreeSize] as? Int64 else {
                return 0 
            }
            return totalDiskSpaceInBytes
        } catch {
            return 0
        }
    }

    func usedDiskSpaceInBytes() -> Int64 {
        return totalDiskSpaceInBytes() - freeDiskSpaceInBytes()
    }

    func totalDiskSpace() -> String {
        let diskSpaceInBytes = totalDiskSpaceInBytes()
        if diskSpaceInBytes > 0 {
            return ByteCountFormatter.string(fromByteCount: diskSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
        }
        return "The total disk space on this device is unknown"
    }

    func freeDiskSpace() -> String {
        let freeSpaceInBytes = freeDiskSpaceInBytes()
        if freeSpaceInBytes > 0 {
            return ByteCountFormatter.string(fromByteCount: freeSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
        }
        return "The free disk space on this device is unknown"
    }

    func usedDiskSpace() -> String {
        let usedSpaceInBytes = totalDiskSpaceInBytes() - freeDiskSpaceInBytes()
        if usedSpaceInBytes > 0 {
            return ByteCountFormatter.string(fromByteCount: usedSpaceInBytes, countStyle: ByteCountFormatter.CountStyle.binary)
        }
        return "The used disk space on this device is unknown"
    }

}

Ve örnek kullanım:

UIDevice.current.totalDiskSpaceInBytes()
UIDevice.current.totalDiskSpace()
UIDevice.current.freeDiskSpaceInBytes()
UIDevice.current.freeDiskSpace()
UIDevice.current.usedDiskSpaceInBytes()
UIDevice.current.usedDiskSpace()

Bunun !yerine guardgüvenli typecastingveya nilkontrol etmek için kullanmayın.
TheTiger

Yorumlarınız için teşekkürler @TheTiger.
abdullahselek

3

İOS> = 6.0 için yeni NSByteCountFormatter. Bu kod, biçimlendirilmiş bir dize olarak kalan boş bayt sayısını alır.

NSError *error = nil;
NSArray * const paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary * const pathAttributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths firstObject] error:&error];
NSAssert(pathAttributes, @"");
NSNumber * const fileSystemSizeInBytes = [pathAttributes objectForKey: NSFileSystemFreeSize];
const long long numberOfBytesRemaining = [fileSystemSizeInBytes longLongValue];
NSByteCountFormatter *byteCountFormatter = [[NSByteCountFormatter alloc] init];
NSString *formattedNmberOfBytesRemaining = [byteCountFormatter stringFromByteCount:numberOfBytesRemaining];

2

Aşağıdaki kod, daha önce ChrisJF tarafından sağlanan yanıtın Swift 3.0 sürümü uygulamasıdır:

func freeSpaceInBytes() -> NSString {

    var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")

    do {
        let dictionary =  try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())
        let freeSpaceSize = ((dictionary[FileAttributeKey.systemFreeSize] as AnyObject).longLongValue)!
        remainingSpace = ByteCountFormatter.string(fromByteCount: freeSpaceSize, countStyle: ByteCountFormatter.CountStyle.file)
    }
    catch let error {
        NSLog(error.localizedDescription)
    }

    return remainingSpace as NSString

}

Neden bu iPhone'un kullanılabilir disk alanı bilgilerinden daha fazlasını döndürüyor? İPhone'ların kurulum menüsünde 998 MB yazıyorsa, bu 1,2 GB döndürür
Umarım

1

için Swift UIDevice uzantısı olarak

extension UIDevice {
    func freeDiskspace() -> NSString {
        let failedResult: String = "Error Obtaining System Memory"
        guard let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last else {
            return failedResult
        }
        do {
            let dictionary = try NSFileManager.defaultManager().attributesOfFileSystemForPath(path)
            if let fileSystemSizeInBytes = dictionary[NSFileSystemSize] as? UInt,
                let freeFileSystemSizeInBytes =     dictionary[NSFileSystemFreeSize] as? UInt {
                    return "Memory \(freeFileSystemSizeInBytes/1024/1024) of \(fileSystemSizeInBytes/1024/1024) Mb available."
            } else {
                    return failedResult
            }
        } catch {
            return failedResult
        }
    }
}

Nasıl kullanılır:

print("\(UIDevice.currentDevice().freeDiskspace())")

Çıktı şu şekilde olacaktır:

Memory 9656 of 207694 Mb available.

1

Bu gönderinin biraz eski olduğunu biliyorum, ancak bu cevabın birine yardımcı olabileceğini düşünüyorum. Cihazdaki kullanılmış / boş / toplam disk alanını bilmek istiyorsanız Luminous'ı kullanabilirsiniz . Swift ile yazılmış. Sadece aramak zorundasın:

Luminous.System.Disk.freeSpace()
Luminous.System.Disk.usedSpace()

veya

Luminous.System.Disk.freeSpaceInBytes()
Luminous.System.Disk.usedSpaceInBytes()

1

Yukarıdaki kodun hızlı uygulanması: -

import UIKit

class DiskInformation: NSObject {

    var totalSpaceInBytes: CLongLong = 0; // total disk space
    var totalFreeSpaceInBytes: CLongLong = 0; //total free space in bytes

    func getTotalDiskSpace() -> String { //get total disk space
        do{
        let space: CLongLong = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemSize] as! CLongLong; //Check for home dirctory and get total system size
            totalSpaceInBytes = space; // set as total space
            return memoryFormatter(space: space); // send the total bytes to formatter method and return the output

        }catch let error{ // Catch error that may be thrown by FileManager
            print("Error is ", error);
        }
        return "Error while getting memory size";
    }

    func getTotalFreeSpace() -> String{ //Get total free space
        do{
            let space: CLongLong = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[FileAttributeKey.systemFreeSize] as! CLongLong;
            totalFreeSpaceInBytes = space;
            return memoryFormatter(space: space);

        }catch let error{
            print("Error is ", error);
        }
        return "Error while getting memory size";
    }

    func getTotalUsedSpace() -> String{ //Get total disk usage from above variable
        return memoryFormatter(space: (totalSpaceInBytes - totalFreeSpaceInBytes));
    }

    func memoryFormatter(space : CLongLong) -> String{ //Format the usage to return value with 2 digits after decimal
        var formattedString: String;

        let totalBytes: Double = 1.0 * Double(space);
        let totalMb: Double = totalBytes / (1024 * 1024);
        let totalGb: Double = totalMb / 1024;
        if (totalGb > 1.0){
            formattedString = String(format: "%.2f", totalGb);
        }else if(totalMb >= 1.0){
            formattedString = String(format: "%.2f", totalMb);
        }else{
            formattedString = String(format: "%.2f", totalBytes);
        }
        return formattedString;
    }


}

Başka herhangi bir sınıftan arayın.

func getDiskInfo(){
        let diskInfo = DiskInformation();
        print("Total disk space is", diskInfo.getTotalDiskSpace(),"Gb");
        print("Total free space is", diskInfo.getTotalFreeSpace(),"Gb");
        print("Total used space is", diskInfo.getTotalUsedSpace(),"Gb");
    }

Döndürülen değeri test ederken, diğer uygulamalar tarafından gösterilenle aynıdır. En azından iPhone 6S + cihazımda. Bu sadece yukarıda gösterilen cevabın hızlı bir şekilde uygulanmasıdır. Ve benim için kabul edilen cevap işe yaramadı.


1

FileManagerUygun hata işleme ve otomatik dize dönüşümü olmayan Swift 5 uzantısı (tercihinize göre bayt sayısını dizeye dönüştürün). Ayrıca FileManager'ın adını takip eder .

extension FileManager {
    func systemFreeSizeBytes() -> Result<Int64, Error> {
        do {
            let attrs = try attributesOfFileSystem(forPath: NSHomeDirectory())
            guard let freeSize = attrs[.systemFreeSize] as? Int64 else {
                return .failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Can't retrieve system free size"]))
            }
            return .success(freeSize)
        } catch {
            return .failure(error)
        }
    }

    func systemSizeBytes() -> Result<Int64, Error> {
         do {
             let attrs = try attributesOfFileSystem(forPath: NSHomeDirectory())
             guard let size = attrs[.systemSize] as? Int64 else {
                 return .failure(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Can't retrieve system size"]))
             }
             return .success(size)
         } catch {
             return .failure(error)
         }
     }
}

Örnek kullanım:

let freeSizeResult = FileManager.default.systemFreeSizeBytes()
switch freeSizeResult {
case .failure(let error):
    print(error)
case .success(let freeSize):
    let freeSizeString = ByteCountFormatter.string(fromByteCount: freeSize, countStyle: .file)
    print("free size: \(freeSizeString)")
}

0

Swift 2.1 sürümünde ChrisJF yanıtı :

func freeSpaceInBytes() -> NSString{

    var remainingSpace = NSLocalizedString("Unknown", comment: "The remaining free disk space on this device is unknown.")

    do {

        let dictionary =  try NSFileManager.defaultManager().attributesOfFileSystemForPath(NSHomeDirectory())
        freeSpaceSize = (dictionary[NSFileSystemFreeSize]?.longLongValue)!
        remainingSpace = NSByteCountFormatter.stringFromByteCount(freeSpaceSize, countStyle: NSByteCountFormatterCountStyle.File)

    }
    catch let error as NSError {

        error.description
        NSLog(error.description)

    }

    return remainingSpace

}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.