應(yīng)用場(chǎng)景:
現(xiàn)在眾多app中都會(huì)有清楚緩存的功能,怎么能精確的計(jì)算緩存文件的大小,從而清除緩存文件呢,下面對(duì)清楚功能做了個(gè)封裝,以后需要實(shí)現(xiàn)此功能的小伙伴,可以直接拿過(guò)去用了哦,非常方便的.
設(shè)計(jì)思路: 可以根據(jù)SDWebImage
框架的思路, 獲取文件夾路徑
--->遍歷所有文件,一個(gè)個(gè)加起來(lái)
--->獲取文件夾下的子路徑
--->利用文件管理者計(jì)算所有文件尺寸
首先我們可封裝一個(gè)工具類,這樣我們用到此功能的時(shí)候就可以直接拿出來(lái)用
- 首先在.h文件中聲明我們封裝的方法名:
#import <Foundation/Foundation.h>
@interface FileTool : NSObject
/**
* 獲取文件夾尺寸
*
* @param directoryPath 文件夾路徑
*
* @return 返回文件夾尺寸
*/
+ (void)getFileSize:(NSString *)directoryPath completion:(void(^)(NSInteger))completion;
/**
* 刪除文件夾所有文件
*
* @param directoryPath 文件夾路徑
*/
+ (void)removeDirectoryPath:(NSString *)directoryPath;
- 作為一名資深的程序員封裝的話,別人使用錯(cuò)誤使用的話,我們應(yīng)該提供一些錯(cuò)誤信息,也就是所謂的拋出異常(在文件.m中實(shí)現(xiàn)方法)
說(shuō)明:為了避免計(jì)算比較大的文件時(shí),計(jì)算時(shí)間會(huì)很久,如果執(zhí)行app跳轉(zhuǎn)的話,會(huì)產(chǎn)生卡頓的現(xiàn)象,所以采用了block回調(diào)的方式
#import "FileTool.h"
@implementation FileTool
+ (void)removeDirectoryPath:(NSString *)directoryPath
{
// 獲取文件管理者
NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDirectory;
BOOL isExist = [mgr fileExistsAtPath:directoryPath isDirectory:&isDirectory];
if (!isExist || !isDirectory) {
// 拋異常
// name:異常名稱
// reason:報(bào)錯(cuò)原因
NSException *excp = [NSException exceptionWithName:@"pathError" reason:@"笨蛋 需要傳入的是文件夾路徑,并且路徑要存在" userInfo:nil];
[excp raise];
}
// 獲取cache文件夾下所有文件,不包括子路徑的子路徑
NSArray *subPaths = [mgr contentsOfDirectoryAtPath:directoryPath error:nil];
for (NSString *subPath in subPaths) {
// 拼接完成全路徑
NSString *filePath = [directoryPath stringByAppendingPathComponent:subPath];
// 刪除路徑
[mgr removeItemAtPath:filePath error:nil];
}
}
// 計(jì)算緩存
+ (void)getFileSize:(NSString *)directoryPath completion:(void(^)(NSInteger))completion
{
// 獲取文件管理者
NSFileManager *mgr = [NSFileManager defaultManager];
BOOL isDirectory;
BOOL isExist = [mgr fileExistsAtPath:directoryPath isDirectory:&isDirectory];
if (!isExist || !isDirectory) {
// 拋異常
// name:異常名稱
// reason:報(bào)錯(cuò)原因
NSException *excp = [NSException exceptionWithName:@"pathError" reason:@"笨蛋 需要傳入的是文件夾路徑,并且路徑要存在" userInfo:nil];
[excp raise];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 獲取文件夾下所有的子路徑,包含子路徑的子路徑
NSArray *subPaths = [mgr subpathsAtPath:directoryPath];
NSInteger totalSize = 0;
for (NSString *subPath in subPaths) {
// 獲取文件全路徑
NSString *filePath = [directoryPath stringByAppendingPathComponent:subPath];
// 判斷隱藏文件
if ([filePath containsString:@".DS"]) continue;
// 判斷是否文件夾
BOOL isDirectory;
// 判斷文件是否存在,并且判斷是否是文件夾
BOOL isExist = [mgr fileExistsAtPath:filePath isDirectory:&isDirectory];
if (!isExist || isDirectory) continue;
// 獲取文件屬性
// attributesOfItemAtPath:只能獲取文件尺寸,獲取文件夾不對(duì),
NSDictionary *attr = [mgr attributesOfItemAtPath:filePath error:nil];
// 獲取文件尺寸
NSInteger fileSize = [attr fileSize];
totalSize += fileSize;
}
// 計(jì)算完成回調(diào)(為了避免計(jì)算大的文件夾,比較耗時(shí),如果直接返回結(jié)果,控制器跳轉(zhuǎn)的時(shí)候回產(chǎn)生卡頓,所以采用block回調(diào)的方式)
dispatch_sync(dispatch_get_main_queue(), ^{
if (completion) {
completion(totalSize);
}
});
});
}
下面我們開始演示下怎么利用這個(gè)工具類
- 在控制器的.m文件中(首先定義個(gè)宏,可以拿到Caches文件路徑,然后設(shè)置個(gè)totalSize屬性,來(lái)強(qiáng)引用這個(gè)尺寸的大小,后面會(huì)用到):
#import "FileTool.h"
@property (nonatomic, assign) NSInteger totalSize;
#define CachePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]
- 在viewDidLoad方法中調(diào)用計(jì)算文件大小的方法
- (void)viewDidLoad {
[super viewDidLoad];
[SVProgressHUD showWithStatus:@"正在計(jì)算緩存尺寸...."];
// 獲取文件夾尺寸
// 文件夾非常小,如果我的文件非常大
[FileTool getFileSize:CachePath completion:^(NSInteger totalSize) {
_totalSize = totalSize;
[self.tableView reloadData];
[SVProgressHUD dismiss];
}];
}
- 寫一個(gè)處理尺寸大小的方法
// 獲取緩存尺寸字符串
- (NSString *)sizeStr
{
NSInteger totalSize = _totalSize;
NSString *sizeStr = @"清除緩存";
// MB KB B
if (totalSize > 1000 * 1000) {
// MB
CGFloat sizeF = totalSize / 1000.0 / 1000.0;
sizeStr = [NSString stringWithFormat:@"%@(%.1fMB)",sizeStr,sizeF];
} else if (totalSize > 1000) {
// KB
CGFloat sizeF = totalSize / 1000.0;
sizeStr = [NSString stringWithFormat:@"%@(%.1fKB)",sizeStr,sizeF];
} else if (totalSize > 0) {
// B
sizeStr = [NSString stringWithFormat:@"%@(%.ldB)",sizeStr,totalSize];
}
return sizeStr;
}
- 在顯示緩存大小的地方顯示尺寸
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 獲取緩存尺寸字符串
cell.textLabel.text = [self sizeStr];
return cell;
}
- 在點(diǎn)擊事件中處理,刪除緩存功能
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 清空緩存
// 刪除文件夾里面所有文件
[FileTool removeDirectoryPath:CachePath];
// 刪除緩存之后,文件大小顯示為0
_totalSize = 0;
[self.tableView reloadData];
}