我希望我的应用程序知道磁盘可用空间何时更改并更新我的视图。系统有通知吗?
3 回答
有点跑题了……但感觉有必要写这个。
为什么有关磁盘空间更改的通知不好?
想想看。有多个问题使得知道“可用”或“使用”空间成为相当强烈的临时/时间点快照,因此更适合被查询而不是被通知。
文件系统(和/或数据库)是“磁盘”(我们称“存储设备”,在本文中称为“磁盘”)之上的抽象层。这尤其意味着,假设如下:
- 已用磁盘空间等于(甚至接近)所有文件大小的总和
- 可用磁盘空间可以完全分配给新创建的文件,或者现有文件可以按该数量增长
- 文件的大小变化(增长或截断)将反映在可用/已用磁盘空间的相等变化中
- 可用磁盘空间是一个准确/确切可知的数量
- 总磁盘空间不变
不正确。
这是因为文件系统可以自由地实现以下技术:
- 压缩 - 使已用空间小于文件大小的总和,并使确切的可用空间不可知,因为无法预测未来要写入的数据的压缩率
- 重复数据删除 - 类似效果(在已用/可用磁盘空间上)
- 快照 - 使文件系统保留“已删除”的数据,因此即使您认为您释放了文件以前使用的空间,磁盘空间也不会“释放”
- 稀疏文件 - 旧技术,可以称之为“零压缩”,即如果写入的所有内容都是零,则不分配磁盘空间
- 空间预留——文件系统可以留出一定数量的空间供特权应用程序/用户使用,和/或仅通过特定接口使用
- 在线文件系统大小调整 - 可能会增加/减少文件系统可用的磁盘总量
- 实时碎片整理 - 可能合并使用的空间
- 块重新分配 - 对于闪存设备,可能会导致擦除块级别的合并,并允许闪存 FTL 释放空间
- 日志滚动 - 可能会根据日志中的事务类型释放或增加使用量
- ……还有什么。
此外,虽然文件大小是字节精确的,但磁盘分配以更大的数量(块/扇区/条带/...)进行管理。
因此,文件系统可以向应用程序世界呈现完全静态的(从哪些文件和目录可见以及它们包含什么的角度)视图,同时例如运行在线重复数据删除/压缩/碎片整理/...作业作为后台活动“将在存储和/或 CPU 能力允许的情况下不断更改“磁盘空间使用”统计信息。
现代文件系统(例如,许多在基于闪存的存储上运行)通常实现上述技术的重要子集,因此,如果它们实现一个接口,将通知“可分配磁盘空间”的每次更改,而不是仅报告可能无意义的数据,但由于它们的“正常”操作可能会引发大量此类通知,因此也会导致显着的性能损失。
尔格:
不要期望得到通知。轮询此信息 -以合理的时间间隔明确查询。不要让 CPU 受限,尤其是在移动设备上,并期望“令人惊讶”的结果,即没有任何明显用户操作的更改以及用户操作发生的更改。对检索到的数据持保留态度,不要从中得出太多结论。那是适合您的现代文件系统...
您可以在此处参考此链接如何检测 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;
}