在编写iOS应用时,我们都会大量把服务器的接口调用数据或者图片数据进行缓存,为了更好的使用体验,有时候我们也会把各种缓存的数据所占的空间大小告诉用户,提供给用户参考,并让用户可以手动清除缓存数据,就像我们在千寻影视中也就提供了这样一个设置项。但是当数据多了之后,就会发现所占空间的大小计算非常耗时,因为缓存下来的是大量的小文件,这就会造成界面很久没有反映的状况。为了解决这种情况,当然是可以通过多线程的方法来做到的,但是在一个简单的设置界面做这么复杂的事情,我倒认为是一个拿起牛刀来杀鸡的行为了。本篇就是来探求一些优化手段,把目录的大小计算耗时降到可以接受的程度。

首先,在iOS当中,要实现一个功能,肯定想到去找objective-c的官方库中是否提供了相关功能,如果有,那就直接用objective-c代码来实现了,通过搜索,很容易就写出这样一个函数:

+ (long long) fileSizeAtPath:(NSString*) filePath{NSFileManager* manager = [NSFileManager defaultManager];if ([manager fileExistsAtPath:filePath]){return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];}return 0;
}

简单可行,但是,我们这里探讨性能,要优化,很容易想到直接使用c代码,跳过objective-c的封装来做,于是,我们这个函数就变成了:

+ (long long) fileSizeAtPath:(NSString*) filePath{struct stat st;if(lstat([filePath cStringUsingEncoding:NSUTF8StringEncoding], &st) == 0){return st.st_size;}return 0;
}

循环1000次,我们就可以发现两者之间巨大的性能差距了,在我的测试环境中,结果如下,c函数的耗时仅是第一种方法的5%

2011-12-31 14:17:22.165 otest[85861:903] [0.041] 使用NSFileManager获取文件大小
2011-12-31 14:17:22.168 otest[85861:903] [0.002] 使用unix c函数获取文件大小

要获取一个目录的总大小,我们就可以写这么一个函数了:

// 循环调用fileSizeAtPath来获取一个目录所占空间大小
+ (long long) folderSizeAtPath2:(NSString*) folderPath{NSFileManager* manager = [NSFileManager defaultManager];if (![manager fileExistsAtPath:folderPath]) return 0;NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];NSString* fileName;long long folderSize = 0;while ((fileName = [childFilesEnumerator nextObject]) != nil){NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];folderSize += [self fileSizeAtPath:fileAbsolutePath];}return folderSize;
}

但是,通过测试,目录遍历本身所带来的时间消耗大大的弱化了我们改进过的fileSizeAtPath函数所带来的优势,导致后者的测试耗时仅是前者的1/2到1/3之间:

2011-12-31 14:17:23.233 otest[85861:903] [0.932] 使用subpathsAtPath然后循环调用NSFileManager获取目录总大小
2011-12-31 14:17:23.582 otest[85861:903] [0.348] 使用subpathsAtPath然后循环调用unix c函数获取目录总大小

既然文件大小的获取可以使用c函数,那么目录的遍历当然可以使用c函数来进行的了,一不做二不休,继续修改优化,代码我就不在继续贴了,附件中有包含了自动测试的整个项目文件,优化后,最终的效果如下:

2011-12-31 14:29:08.520 otest[87180:903] [0.915] 使用subpathsAtPath然后循环调用NSFileManager获取目录总大小
2011-12-31 14:29:08.860 otest[87180:903] [0.339] 使用subpathsAtPath然后循环调用unix c函数获取目录总大小
2011-12-31 14:29:08.953 otest[87180:903] [0.092] 使用纯unix c递归获取目录总大小

项目源代码文件下载点击这里

本篇转自我自己的个人博客站 iOS中使用c函数快速获取一个目录所占的空间大小

iOS中使用c函数快速获取一个目录所占的空间大小相关推荐

  1. 快速获取一个网站的所有资源,图片,html,css,js......扒站,仿站必备工具

    今天介绍一款软件,可以快速获取一个网站的所有资源,图片,html,css,js...... 以获取某车官网为例 我来展示一下这个软件的功能. 输入网站地址和网站要保存的文件夹 如果网站名称后我们可以扫 ...

  2. python随机产生100个整数二进制_PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。...

    Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...

  3. FileDemo4~5 获取一个目录中的所有子项/部分子项

    FileDemo4 获取一个目录中的所有子项 /** *    获取一个目录中的所有子项 *    方法:    File[] listFiles() *    重载方法: File[] listFi ...

  4. Windows下快速获取一个文件夹下所有文件的名称列表

    Windows下快速获取一个文件夹下所有文件的名称列表 进入windows终端:win+R 输入cmd,回车 使用cd命令进入到目标文件夹.例如: 先进入D盘,输入d: 回车, 然后 cd openc ...

  5. python让用户输入一个整数_PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。...

    Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...

  6. java 获取子文件夹_JAVA之File类 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件...

    package ioTest.io3; import java.io.File; /* * 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件 . * 并将文件夹和文件名称打印在控制台上面.并且要 ...

  7. glob php,php使用glob函数快速查询指定目录文件的方法

    本文实例讲述了php使用glob函数快速查询指定目录文件的方法.分享给大家供大家参考.具体如下: php搜索当前目录所有文件,代码如下: $array = glob('*.*'); print_r($ ...

  8. java map 随机取值_随机获取一个集合(List, Set)中的元素,随机获取一个Map中的key或value...

    利用Java提供的Random类.从List或Set中随机取出一个元素,从Map中随机获取一个key或value. 因为Set没有提供get(int index)方法,仅仅能先获取一个随机数后.利用一 ...

  9. 获取一个目录下的所有文件

    知道一个目录的路径,使用递归获取该目录下的所有文件: function rDir($filepath) { $result = array();//获取的结果保存在这个数组中 if(is_dir($f ...

最新文章

  1. 《JavaScript高级程序设计(第3版)》教程大纲
  2. 90后招你惹你了?去你的佛系!
  3. 肝货!你想要的资源这里都有!
  4. 【WC2016】挑战NPC 【带花树】【建图】
  5. TDD:MS自带的单元测试 之 线程模型和执行顺序
  6. 人工智能AI实战100讲(一)-机器人语义建图(下)
  7. epoll在ET和LT模式下读写
  8. 僵尸矩阵 · Zombie in Matrix
  9. Lintcode 730 所有子集的和
  10. java详细设计模式有代码
  11. 系统分析师学习笔记(十七)
  12. 原码/补码的加减运算and溢出判断
  13. android实现拍照及获取照片上传至接口
  14. SpringBoot登录验证码实现
  15. L1 loss 是什么
  16. Openvino 模型转换命令mo.py
  17. Ubuntu安装jdk(java环境)
  18. iPhone卫星功能仅用于紧急通信;韩国通过立法禁止苹果、谷歌垄断支付系统;Linux 5.14 版本发布|极客头条
  19. android gettext方法,android – getString()和getText()有什么区别?
  20. Splunk 会议回顾: 大数据的关键是机器学习

热门文章

  1. 亿信华辰:避免数字化转型失败的3大破局思路和4点建议
  2. 人工智能多媒体课件-中南大学-蔡自兴 主编
  3. sFlow、NetFlow、SNMP三者之间有什么不同?
  4. 【数字信号处理】离散信号与系统分析
  5. 建立新闻内容的数据库_使用数据新闻学产生内容创意
  6. 【paper笔记】ESAM: Discriminative Domain Adaptation with Non-Displayed Items to Improve Long-Tail
  7. CC2640R2F工程之间相互转换
  8. 2021-05-04
  9. 第二讲:认识颜色符号或绘图函数
  10. word怎么排版两列