-2

我希望我的应用程序知道磁盘可用空间何时更改并更新我的视图。系统有通知吗?

4

3 回答 3

7

有点跑题了……但感觉有必要写这个。

为什么有关磁盘空间更改的通知不好?

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

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

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

正确

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

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

此外,虽然文件大小是字节精确的,但磁盘分配以更大的数量(块/扇区/条带/...)进行管理。

因此,文件系统可以向应用程序世界呈现完全静态的(从哪些文件和目录可见以及它们包含什么的角度)视图,同时例如运行在线重复数据删除/压缩/碎片整理/...作业作为后台活动“将在存储和/或 CPU 能力允许的情况下不断更改“磁盘空间使用”统计信息。

现代文件系统(例如,许多在基于闪存的存储上运行)通常实现上述技术的重要子集,因此,如果它们实现一个接口,将通知“可分配磁盘空间”的每次更改,而不是仅报告可能无意义的数据,但由于它们的“正常”操作可能会引发大量此类通知,因此也会导致显着的性能损失。

尔格:

不要期望得到通知。轮询此信息 -以合理的时间间隔明确查询。不要让 CPU 受限,尤其是在移动设备上,并期望“令人惊讶”的结果,即没有任何明显用户操作的更改以及用户操作发生的更改。对检索到的数据持保留态度,不要从中得出太多结论。那是适合您的现代文件系统...

于 2013-01-30T12:55:33.967 回答
1

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

但幸运的是,您可以自己监控剩余可用空间的大小,并在发现变化时做一些事情。

查看如何检测 iPhone/iPad 设备上的总可用/空闲磁盘空间?看看如何。

于 2013-01-30T11:05:51.407 回答
0

您可以在此处参考此链接如何检测 iPhone/iPad 设备上的总可用/可用磁盘空间?

你可以试试这个。

-(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;
}
于 2013-01-30T10:57:28.740 回答