如何监控iOS磁盘空间的变化?

时间:2013-01-30 10:47:01

标签: ios notifications filesystems

我希望我的应用知道磁盘可用空间何时更改并更新我的视图。系统是否发送了任何通知?

3 个答案:

答案 0 :(得分:7)

稍微偏离主题......但感觉不得不写这个。

为什么有关磁盘空间的通知会发生变化?

想一想。有许多问题使得“可用”或“使用”空间成为一个相当强烈的临时/时间点快照,因此比通知更适合查询

文件系统(和/或数据库)是“磁盘”之上的抽象层(让我们称之为“存储设备”,为了这个帖子,“磁盘”)。这尤其意味着如下假设:

  • 已用磁盘空间等于(甚至接近)所有文件大小的总和
  • 可以将可用磁盘空间完全分配给新创建的文件,或者可以使用该数量增加现有文件
  • 文件的大小更改(增长或截断)将反映在相等的空闲/已用磁盘空间中
  • 可用磁盘空间是确切/完全可知的数量
  • 总磁盘空间不变

不正确

那是因为文件系统可以自由地实现以下技术:

  1. 压缩 - 使用的空间小于文件大小的总和,并使精确的可用空间不可知,因为无法预测将来要写入的数据的压缩率
  2. 重复数据删除 - 类似的效果(在已用/可用磁盘空间上)
  3. 快照 - 使文件系统保留“已删除”数据,因此即使您认为已释放文件以前使用过的空间,也不会“释放”磁盘空间
  4. 稀疏文件 - 旧技术,可以称之为“零压缩”,即如果所有写入的都是零,则不分配磁盘空间
  5. 空间预留 - 文件系统可以留出一定数量的空间,仅供特权应用/用户使用,和/或仅用于通过特定接口使用
  6. 在线文件系统调整大小 - 可能会增加/缩小文件系统可用的磁盘总量
  7. 实时碎片整理 - 可能会合并已用空间
  8. 阻止重新分配 - 对于闪存设备,可能会导致擦除块级别的合并并允许闪存FTL释放空间
  9. 日记滚动 - 可能会释放或增加使用量,具体取决于日志中的事务类型
  10. ......什么不是。
  11. 此外,虽然文件大小是字节精确的,但磁盘分配是以较大的数量(块/扇区/条带/ ...)进行管理。

    因此,文件系统可以向应用程序世界提供完全静态的(从查看哪些文件和目录是可见的以及它们包含的内容)视图,例如,运行联机重复数据删除/压缩/碎片整理/ ...作为后台活动,将不断更改“磁盘空间使用”统计数据,与存储和/或CPU功率一样快。

    现代文件系统(许多在基于闪存的存储上运行)经常实现上述技术的重要子集,因此他们是否会实现一个“通知的接口” “可分配磁盘空间”中的每一个变化,不仅报告可能无意义的数据,而且还因其“正常”操作而导致显着的性能损失,可能会导致大量此类通知。

    <强>埃尔戈:

    不希望收到通知。轮询此信息 - 以合理的间隔明确查询。不要受CPU限制,特别是不要在移动设备上,并期望“令人惊讶”的结果,即没有任何明显的用户操作的变化以及用户操作发生时没有变化。把你检索到的数据用一粒盐取出来,不要从中得出太多结论。这是现代文件系统...

答案 1 :(得分:1)

不,系统没有发布任何通知。

但幸运的是,您可以自己监控剩余可用空间的大小,并在发现变化时执行某些操作。

查看How to detect total available/free disk space on the iPhone/iPad device?以了解具体方法。

答案 2 :(得分:0)

您可以在How to detect total available/free disk space on the iPhone/iPad device?

中引用此链接

你可以试试这个。

-(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;
}

这也是

-(uint64_t)getFreeDiskspace {
    uint64_t totalSpace = 0.0f;
    uint64_t totalFreeSpace = 0.0f;
    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 floatValue];
        totalFreeSpace = [freeFileSystemSizeInBytes floatValue];
        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 = %@", [error domain], [error code]);  
    }  

    return totalFreeSpace;
}