1. 程式人生 > >iOS開發 清空沙盒路徑下的快取資料

iOS開發 清空沙盒路徑下的快取資料

引言:

移動應用在處理網路資源時,一般都會做離線快取處理,其中以圖片快取最為典型,其中很流行的離線快取框架為 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;
}

使用的時候只需要傳入路徑就可以了!!!


本篇文章對應的原始碼下載地址:ClearCacheDemo