美文网首页
iOS开发 - 文件读写数据缓存

iOS开发 - 文件读写数据缓存

作者: 阿唯不知道 | 来源:发表于2019-05-09 14:41 被阅读0次

    对一些首页的网络加载的数据进行本地缓存,提升用户体验,不至于每次进入首页都是一片空白,这里使用的是文件读写的方式,直接将网络请求返回的json数据进行读写操作

    YWDataCache.h文件

    #import <Foundation/Foundation.h>
    
    // 主缓存路径,默认放在 /Library/Caches/default 这个路径下
    #define YWCachePath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] stringByAppendingString:@"/default"]
    // 日志打印
    #ifdef DEBUG
    #   define YWLog(fmt, ...) NSLog((@"\n⭐️⭐️⭐️: %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
    #else
    #   define YWLog(...)
    #endif
    
    @interface YWDataCache : NSObject
    
    /**
     普通json缓存 - 写入缓存
    
     @param fileName        缓存文件名称(读取时保持一致)
     @param dataSource      要缓存的数据源
     @return                返回写入结果 YES Or NO
     */
    + (BOOL)writeDataToCacheWithFileName:(NSString *)fileName dataSource:(id)dataSource;
    
    /**
     普通json缓存 - 读取缓存
    
     @param fileName        缓存文件名称(读写要保持一致)
     @return                返回读取结果
     */
    + (nullable id)getCacheWithFileName:(NSString *)fileName;
    
    /**
     HTML缓存 - 写入缓存
    
     @param urlString       网页链接Url
     @return                返回写入结果 YES Or NO
     */
    + (BOOL)writeToHTMLCache:(NSString *)urlString;
    
    /**
     HTML缓存 - 读取缓存
    
     @param urlString       网页链接Url
     @return                返回html标签文件
     */
    + (NSString *)getHTMLCacheWithUrlString:(NSString *)urlString;
    
    
    /**
     *
     @param urlString       图片url
     @return                返回写入结果 YES Or NO
     */
    
    /**
     网络图片缓存 - 写入缓存
    
     @param urlString       图片url
     @param successBlock    成功回调
     @param errorBlock      失败回调
     */
    + (void)writeImageToLocalCache:(NSString *)urlString successBlock:(void (^)(UIImage *))successBlock errorBlock:(void (^)(void))errorBlock;
    
    /**
     网络图片缓存 - 读取缓存
    
     @param urlString       图片url
     @return                返回读取结果
     */
    + (UIImage *)getImageWithImageUrl:(NSString *)urlString;
    
    /**
     获取path路径下文件夹的大小
    
     @param path            要获取的文件夹 路径
     @return                返回path路径下缓存文件大小
     */
    + (NSString *)getCacheSizeWithFilePath:(NSString *)path;
    
    /**
     清除path路径下文件夹的缓存
    
     @param path            要清除缓存的文件夹 路径
     @return                返回是否清除成功
     */
    + (BOOL)clearCacheWithFilePath:(NSString *)path;
    
    
    /**
     数据大小转换(bytes转 MB、KB、B)
    
     @param dataLength      数据长度
     @return                返回大小字符串
     */
    + (NSString *)getBytesFromDataLength:(NSInteger)dataLength;
    
    @end
    
    

    YWDataCache.m文件

    #import "YWDataCache.h"
    @implementation YWDataCache
    
    
    #pragma mark - * * * * * 普通json缓存 * * * * *
    // 普通json缓存 - 写入缓存
    + (BOOL)writeDataToCacheWithFileName:(NSString *)fileName dataSource:(id)dataSource {
        
        // 检查文件夹是否存在
        [self checkFolderIsExistsWithFilePath:nil];
        // 拼接缓存路径
        NSString *cachesPath = [NSString stringWithFormat:@"%@/%@.json", YWCachePath, fileName];
        NSError *error;
        NSData *data = [NSJSONSerialization dataWithJSONObject:dataSource options:NSJSONWritingPrettyPrinted error:&error];
        BOOL isTureWrite = [data writeToFile:cachesPath atomically:YES];
        if (isTureWrite) {
            YWLog(@"数据写入成功,缓存路径:%@", cachesPath);
            return YES;
        }
        YWLog(@"数据写入失败,错误消息:%@,%@", fileName, error);
        return NO;
    }
    
    // 普通json缓存 - 读取缓存
    + (nullable id)getCacheWithFileName:(NSString *)fileName {
        
        // 检查文件夹是否存在
        [self checkFolderIsExistsWithFilePath:nil];
        // 拼接缓存路径
        NSString *cachesPath = [NSString stringWithFormat:@"%@/%@.json", YWCachePath, fileName];
        NSData *data = [NSData dataWithContentsOfFile:cachesPath];
        if (data) {
            NSError *error;
            id dataSource = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error];
            if (!error) {
                return dataSource;
            }
            YWLog(@"数据读取失败,错误消息:%@,%@", fileName, error);
        }
        YWLog(@"暂无缓存数据");
        return nil;
        
    }
    
    #pragma mark - * * * * * 网页缓存 * * * * *
    // 网页缓存写入文件
    + (BOOL)writeToHTMLCache:(NSString *)urlString {
        
        // 检查文件夹是否存在
        [self checkFolderIsExistsWithFilePath:nil];
        // 拼接缓存路径
        NSString *cachesPath = [NSString stringWithFormat:@"%@/%lu.html", YWCachePath, (unsigned long)[urlString hash]];
        // URL编码
        NSString * htmlResponseStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSUTF8StringEncoding error:Nil];
        // 将文件写入缓存
        NSError *error;
        BOOL isTureWrite = [htmlResponseStr writeToFile:cachesPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
        if (isTureWrite) {
            YWLog(@"网页数据写入成功,缓存路径:%@", cachesPath);
            return YES;
        }
        YWLog(@"网页数据写入失败,错误消息:%@,%@", urlString, error);
        return NO;
    }
    // 读取网页缓存
    + (NSString *)getHTMLCacheWithUrlString:(NSString *)urlString {
        
        // 检查文件夹是否存在
        [self checkFolderIsExistsWithFilePath:nil];
        // 拼接缓存路径
        NSString *cachesPath = [NSString stringWithFormat:@"%@/%lu.html", YWCachePath, (unsigned long)[urlString hash]];
        // 读取缓存文件
        NSError *error;
        NSString *htmlStr = [NSString stringWithContentsOfFile:cachesPath encoding:NSUTF8StringEncoding error:nil];
        if (!error) {
             return htmlStr;
        }
        YWLog(@"网页数据读取失败,错误消息:%@,%@", urlString, error);
        return nil;
    }
    
    #pragma mark - * * * * * 网络图片缓存 * * * * *
    + (void)writeImageToLocalCache:(NSString *)urlString successBlock:(void (^)(UIImage *image))successBlock errorBlock:(void (^)(void))errorBlock {
        
        if (!urlString && errorBlock) {
            errorBlock();
        }
        
        dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^(void) {
            
            NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]];
            UIImage *image = [[UIImage alloc] initWithData:data];
            dispatch_async( dispatch_get_main_queue(), ^(void){
                if(image && successBlock) {
                    
                    NSString *imageFilePath = [NSString stringWithFormat:@"%@/%@.jpg", YWCachePath, [urlString qmui_md5]];
                    //写入本地文件
                    if ([UIImageJPEGRepresentation(image, 1.0f) writeToFile:imageFilePath atomically:YES]) {
                        successBlock(image);
                    }
                }else {
                    if (errorBlock) errorBlock();
                }
            });
        });
    }
    
    // 读取缓存图片
    + (UIImage *)getImageWithImageUrl:(NSString *)urlString {
        if (!urlString) {
            YWLog(@"暂无缓存数据");
            return nil;
        }
        // 拼接缓存路径
        NSString *cachesPath = [NSString stringWithFormat:@"%@/%@.jpg", YWCachePath, [urlString qmui_md5]];
        NSData *data = [NSData dataWithContentsOfFile:cachesPath];
        if (data) {
            UIImage *image = [[UIImage alloc] initWithData:data];
            if (image) {
                return image;
            }
        }
        YWLog(@"暂无缓存数据");
        return nil;
    }
    
    #pragma mark - 获取path路径下文件夹大小
    + (NSString *)getCacheSizeWithFilePath:(NSString *)path {
        
        // 如果传入的路径为空,则直接统计 默认路径:YWCachePath 的缓存
        if (!path || [path isEqualToString:@""]) {
            path = YWCachePath;
        }
        // 获取“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 = totleSize ? [self getBytesFromDataLength:totleSize] : @"0.00MB";
        
        return totleStr;
    }
    
    
    #pragma mark - 清除path文件夹下缓存大小
    + (BOOL)clearCacheWithFilePath:(NSString *)path{
        
        // 如果传入的路径为空,则直接清除 默认路径:YWCachePath 的缓存
        if (!path || [path isEqualToString:@""]) {
            path = YWCachePath;
        }
        
        //拿到path路径的下一级目录的子文件夹
        NSArray *subPathArr = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
        
        NSString *filePath = nil;
        NSError *error = nil;
        
        if (!subPathArr) {
            // 直接清理指定路径下的文件
             [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
        }else {
            for (NSString *subPath in subPathArr) {
                filePath = [path stringByAppendingPathComponent:subPath];
                if (![filePath containsString:@"/Caches/Snapshots"]) {
                    //删除子文件
                    [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
                }
            }
        }
        
        if (!error) {
            YWLog(@"缓存清除成功");
            return YES;
        }
        YWLog(@"缓存清除失败,错误信息:%@",error);
        return NO;
    }
    
    
    + (NSString *)getBytesFromDataLength:(NSInteger)dataLength {
        NSString *bytes;
        
        if (dataLength >= 0.5 * (1024 * 1024 * 1024)) {
            bytes = [NSString stringWithFormat:@"%0.2fGB",dataLength/1024/1024.0/1024.0];
        } else if (dataLength >= 0.5 * (1024 * 1024)) {
            bytes = [NSString stringWithFormat:@"%0.2fMB",dataLength/1024/1024.0];
        } else if (dataLength >= 1024) {
            bytes = [NSString stringWithFormat:@"%0.2fKB",dataLength/1024.0];
        } else {
            bytes = [NSString stringWithFormat:@"%zdB",dataLength];
        }
        return bytes;
    }
    
    
    #pragma mark - * * * * * private * * * * *
    // 检查文件夹是否存在
    + (BOOL)checkFolderIsExistsWithFilePath:(NSString *)path {
        
        // 如果传入的路径为空,则直接清除 默认路径:YWCachePath 的缓存
        if (!path || [path isEqualToString:@""]) {
            path = YWCachePath;
        }
        // 创建一个文件管理器
        NSFileManager *manager = [NSFileManager defaultManager];
        // 检查文件夹是否存在
        BOOL isExists = [manager fileExistsAtPath:path];
        if (!isExists) {
            // 创建文件夹
            return [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
        }
        return YES;
    }
    
    @end
    
    

    相关文章

      网友评论

          本文标题:iOS开发 - 文件读写数据缓存

          本文链接:https://www.haomeiwen.com/subject/grewoqtx.html