引言:
移動應用在處理網絡資源時,一般都會做離線緩存處理,其中以圖片緩存最為典型,其中很流行的離線緩存框架為 SDWebImage 。
但是,離線緩存會占用手機存儲空間,所以緩存清理功能基本成為資訊、購物、閱讀類 App 的標配功能。
由于緩存文件是存在 App 的沙盒中,所以我們可以通過 NSFileManager API 來實現對緩存文件大小的計算和數據的刪除操作。
我們先來了解一下沙盒機制:
沙盒:iOS系統為每一個應用程序創建一個文件目錄,是一個的獨立,封閉,安全的空間, 一個沙盒就是一個文件目錄。沙盒規定了一個程序只能在自身的沙盒中進行操作,不能去訪問其他應用程序的沙盒(iOS8已經部分開放訪問)
沙盒的作用: 用來存放非代碼文件(圖片, 音頻, 視頻, 屬性列表(plist), sqlite數據庫, 文本文件, 其他等等)
沙盒中常用的幾個路徑:
Document文件夾:
用來保存應由程序運行時生成的需要持久化的數據, iTunes會自動備份該目錄(蘋果公司建議將程序中創建的和瀏覽過的程序存放在這里,iTunes在備份和回復時會自動包含此目錄)。
獲取方法:
//文件路徑是數組,這里取第一個元素
NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];`
Library文件夾:
用來存儲程序的默認設置和其他狀態信息,iTunes也會自動備份該目錄。
獲取方法:
NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
Library/Caches:
用來存放緩存文件,iTunes不會備份此目錄,此目錄下的文件不會在程序退出后刪除,一般存放體積比較大但又不太重要的文件。
獲取方法:
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
**Library/Preferences: **
用來存儲用戶的偏好設置,iOS的setting(設置)會在這個目錄中查找應用程序的設置信息,iTunes會自動備份該目錄,通常這個文件夾都是由系統進行維護的,建議不要操作他。
系統沒有直接獲取這個文件夾路徑的方法,需要先獲取Library路徑然后進行字符串拼接找到此路徑:
NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDoMainMask, YES)[0];
NSString*preferencePath = [libraryPath stringByAppendingString:@“/Preferences”];
注意:不要直接寫偏好設置到這個文件夾,而是通過NSUserDefaults來進行偏好設置的保存和讀取。
tmp:
保存應用程序的臨時文件夾,使用完畢后,將相應的文件從這個目錄中刪除,如果空間不夠,系統也可能會刪除這個目錄下的文件,iTunes不會同步這個文件夾,在iPhone重啟的時候,該目錄下的文件會被刪除。
這個路徑的獲取方法和其他的不同,它有自己方法:
NSString *tmpPath = NSTemporaryDirectory();
下面直接上代碼:
我們可以封裝成一個工具類: ClearCacheTool類。
ClearCacheTool.h文件:
#import <Foundation/Foundation.h>
@interface ClearCacheTool : NSObject
/*s*
* 獲取path路徑下文件夾的大小
*
* @param path 要獲取的文件夾 路徑
*
* @return 返回path路徑下文件夾的大小
*/
+ (NSString *)getCacheSizeWithFilePath:(NSString *)path;
/**
* 清除path路徑下文件夾的緩存
*
* @param path 要清除緩存的文件夾 路徑
*
* @return 是否清除成功
*/
+ (BOOL)clearCacheWithFilePath:(NSString *)path;
ClearCacheTool.m文件:
#import "ClearCacheTool.h"
@implementation ClearCacheTool
#pragma mark - 獲取path路徑下文件夾大小
+ (NSString *)getCacheSizeWithFilePath:(NSString *)path{
// 獲取“path”文件夾下的所有文件
NSArray *subPathArr = [[NSFileManager defaultManager] subpathsAtPath:path];
NSString *filePath = nil;
NSInteger totleSize = 0;
for (NSString *subPath in subPathArr){
// 1. 拼接每一個文件的全路徑
filePath =[path stringByAppendingPathComponent:subPath];
// 2. 是否是文件夾,默認不是
BOOL isDirectory = NO;
// 3. 判斷文件是否存在
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory];
// 4. 以上判斷目的是忽略不需要計算的文件
if (!isExist || isDirectory || [filePath containsString:@".DS"]){
// 過濾: 1. 文件夾不存在 2. 過濾文件夾 3. 隱藏文件
continue;
}
// 5. 指定路徑,獲取這個路徑的屬性
NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
/**
attributesOfItemAtPath: 文件夾路徑
該方法只能獲取文件的屬性, 無法獲取文件夾屬性, 所以也是需要遍歷文件夾的每一個文件的原因
*/
// 6. 獲取每一個文件的大小
NSInteger size = [dict[@"NSFileSize"] integerValue];
// 7. 計算總大小
totleSize += size;
}
//8. 將文件夾大小轉換為 M/KB/B
NSString *totleStr = nil;
if (totleSize > 1000 * 1000){
totleStr = [NSString stringWithFormat:@"%.2fM",totleSize / 1000.00f /1000.00f];
}else if (totleSize > 1000){
totleStr = [NSString stringWithFormat:@"%.2fKB",totleSize / 1000.00f ];
}else{
totleStr = [NSString stringWithFormat:@"%.2fB",totleSize / 1.00f];
}
return totleStr;
}
#pragma mark - 清除path文件夾下緩存大小
+ (BOOL)clearCacheWithFilePath:(NSString *)path{
//拿到path路徑的下一級目錄的子文件夾
NSArray *subPathArr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSString *filePath = nil;
NSError *error = nil;
for (NSString *subPath in subPathArr)
{
filePath = [path stringByAppendingPathComponent:subPath];
//刪除子文件夾
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
if (error) {
return NO;
}
}
return YES;
}
使用的時候只需要傳入路徑就可以了?。?!
<br />
本篇文章對應的源代碼下載地址:ClearCacheDemo
<br />
<br />
GitHub: https://github.com/LiCheng244/LCUtils
個人博客: http://www.licheng244.com/