归档和解档、沙盒路径

一、数据归档 解档

  • 特点

“归档”是一种可以把任何对象,直接保存为文件的方式。(其中包括”归档”与”反归档(读档)”)
* 使用前提
必须是实现协议 ,通过”归档”的方式来存储,对象必须遵守NSCoding协议,也就意味着通过”归档”的方式能 将任何遵守了NSCoding协议的”对象”存储到文件中 (对象要是使用归档 解档 要遵守 NSCoding 协议)

  • 归档、解档 :将一个对象写到文件

归档:创建一个NSKeyedArchiver实例,用于将对象归档到一个NSMutableData实例中,此时NSMutableData包含编码的数据,再使用键/码对需要的对象进行归档,最后告知完成,写入文件系统;

解档:也与归档对象步骤类似,创建一个NSData实例用于装载数据,并创建一个NSKeyedUnarchiver实例,对数据解码,然后使用先前用的键进行读取对象,最后告知程序解档完成;

归档/解档

这个方法一个对象归档成一个文件
    //归档
    NSArray *array = [NSArray arrayWithObjects:@"zhang",@"wangwu",@"lisi",nil]; 
    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.src"]; 

    BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:filePath]; 
    if(success){ 
    NSLog(@"保存成功"); 
    }   

    //解档 
    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.src"]; 
    id array = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 
    NSLog(@"%@",array);

归档

(此方法可以 多个对象归档成一个文件)
+ (BOOL)archive:(BJMBOUserModel *_Nonnull)model
{
// 获取路劲
 NSString *__path4Cache = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
 改修后缀名,以免与属性列表创建的文件重复,而加载成旧的的文件。 不用查字典了。。archive表归档
    NSString *__filePath4Archive = [__path4Cache stringByAppendingPathComponent:ARCHIVE_FILE_PATH_FOR_USER_MODEL];
    //判断文件是否可以操作
    if (![[NSFileManager defaultManager] fileExistsAtPath:__filePath4Archive]) {
        BOOL __created = [[NSFileManager defaultManager] createFileAtPath:__filePath4Archive contents:nil attributes:nil];
        if (!__created) {
            return false;
        }
    }
    NSMutableData *__data = [[NSMutableData alloc] init];
    NSKeyedArchiver *__archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:__data];
    //使用键/值编码对希望包含在归档中的对象进行归档。
    [__archiver encodeObject:model forKey:ARCHIVE_FILE_PATH_FOR_USER_MODEL];
    [__archiver finishEncoding];
    与属性列表一样,需要在最后写入文件,因为属性列表与归档都是一种序列化,最后仍需要写入文件。
    BOOL isArchiveSuccess = [__data writeToFile:__filePath4Archive atomically:true];
    return isArchiveSuccess; 
}

解档

(此方法可以 解档多个对象)
+ (BJMBOUserModel *_Nullable)unarchive
{
   NSString *__path4Cache = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
    NSString *__filePath4Archive = [__path4Cache stringByAppendingPathComponent:ARCHIVE_FILE_PATH_FOR_USER_MODEL];
    if ([[NSFileManager defaultManager] fileExistsAtPath:__filePath4Archive]) {
        NSData *__data4Archived = [NSData dataWithContentsOfFile:__filePath4Archive];
        if (__data4Archived) {
            NSKeyedUnarchiver *__unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:__data4Archived];
            id __obj4Unarchived = [__unarchiver decodeObjectForKey:ARCHIVE_FILE_PATH_FOR_USER_MODEL];
            [__unarchiver finishDecoding];   //完成解档
            if ([__obj4Unarchived isKindOfClass:[BJMBOUserModel class]]) {
                BJMBOUserModel *__userModel = (BJMBOUserModel *)__obj4Unarchived;
                return __userModel;
            }
            return nil;
        }
    }
    return nil;
}

归档解档通用路径处理

-(NSString *)dataFile
{
    //应用沙盒地址,返回的是一个数组
    NSString *__path4Cache = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
    // 拼接路径
    NSString *__filePath4Archive = [__path4Cache stringByAppendingPathComponent:ARCHIVE_FILE_PATH_FOR_USER_MODEL];

}

删除文件

+ (BOOL)deleteFile
{
    // 获取要删除的路径
    NSString *__path4Cache = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject];
    NSString *__filePath4Archive = [__path4Cache stringByAppendingPathComponent:ARCHIVE_FILE_PATH_FOR_USER_MODEL];
    // 创建文件管理对象
    NSFileManager *manager = [NSFileManager defaultManager];

    if ([[NSFileManager defaultManager] fileExistsAtPath:__filePath4Archive]) {
        // 删除
        BOOL isDelete = [manager removeItemAtPath:__filePath4Archive error:nil];
        NSLog(@"%d", isDelete);
        [BJMBOUserManager sharedInstance].curUserModel = nil;
        return YES;
    }
    else{
        // 不存在,也返回 Yes
        return YES;
    }

    return NO;
}

二、应用沙盒目录

Application应用程序包:包含了所有的资源文件和和可执行文件,上架前经过数字签名,上架后不可修改 [NSBundle mainBundle];

  • Documents:保存应用程序本身运行时产生的文件或者数据,iCloud备份目录,例如:游戏进度、涂鸦软件的绘图
    • 注意点:不要保存从网络上下载的文件,否则会无法上架!
  • Library
    • Caches:存放体积大又不需要备份的数据
      • 保存临时文件,”后续需要使用”,例如:缓存图片,离线数据(地图数据)
      • 系统不会清理 cache 目录中的文件
      • 就要求程序开发时,”必须提供 cache 目录的清理解决方案”
    • Preference:保存应用的所有偏好设置,iCloud会备份设置信息
      • 用户偏好,使用 NSUserDefault 直接读写!
      • 如果要想数据及时写入磁盘,还需要调用一个同步方法
  • tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能
    • 保存临时文件,”后续不需要使用”
    • tmp 目录中的文件,系统会自动清理
    • 重新启动手机,tmp 目录会被清空
    • 系统磁盘空间不足时,系统也会自动清理

2.1 应用沙盒目录的常见获取方式

  1. 获取根目录
NSString*home = NSHomeDirectory();
  1. Documents目录 2种方式
    • 利用沙盒根目录拼接”Documents”字符串
    • 注意:不建议采用,因为新版本的操作系统可能会修改目录名
NSString*home = NSHomeDirectory();
NSString*documents =[home stringByAppendingPathComponent:@"Documents"];
  • 利用NSSearchPathForDirectoriesInDomains函数
// NSUserDomainMask 代表从用户文件夹下找
// YES 代表展开路径中的波浪字符“~”
NSArray*array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
// 在iOS中,只有一个目录跟传入的参数匹配,所以这个集合里面只有一个元素
NSString*documents =[array objectAtIndex:0];
  1. tmp临时目录
NSString *tmp = NSTemporaryDirectory();
  1. Library/Caches 目录
    • 方式一:利用沙盒根目录拼接”Caches”字符串
    • 方式二:利用NSSearchPathForDirectoriesInDomains函数(将函数的第2个参数改为:NSCachesDirectory即可)
//获取Documents目录路径的方法:
NSString*documents =[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, NO) objectAtIndex:0]];
  1. Library/Preference 偏好设置
    • 通过NSUserDefaults类存取该目录下的设置信息
- (IBAction)save:(id)sender {
    // 获取偏好设置"单例"
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    // 存储数据
    [ud setObject:@"123" forKey:@"name"];
    [ud setBool:YES forKey:@"isOpen"];
    // 立即写入
    [ud synchronize];

}
- (IBAction)read:(id)sender {
    // 获取偏好设置"单例"
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; 

    //读取数据 
   NSString *name = [ud objectForKey:@"name"];
   BOOL open = [ud boolForKey:@"isOpen"];
    NSLog(@"%@", name);

}

三、文件操作

1. 创建文件夹:
 //创建文件夹  
-(void *)createDir{  
    NSString *documentsPath =[self dirDoc];  
    NSFileManager *fileManager = [NSFileManager defaultManager];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    // 创建目录  
    BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];  
    if (res) {  
        NSLog(@"文件夹创建成功");  
    }else  
        NSLog(@"文件夹创建失败");  
    } 
2. 创建文件
//创建文件  
-(void *)createFile{  
   NSString *documentsPath =[self dirDoc];  
  NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
  NSFileManager *fileManager = [NSFileManager defaultManager];  
  NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
  BOOL res=[fileManager createFileAtPath:testPath contents:nil attributes:nil];  
   if (res) {  
       NSLog(@"文件创建成功: %@" ,testPath);  
   }else {

   } 
}  
3.写数据到文件
//写文件  
 -(void)writeFile{  
   NSString *documentsPath =[self dirDoc];  
   NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
   NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
   NSString *content=@"测试写入内容!";  
   BOOL res=[content writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:nil];  
   if (res) {  
        NSLog(@"文件写入成功");  
    }else  
        NSLog(@"文件写入失败");  
}
4. 读文件数据
//读文件  
-(void)readFile{  
   NSString *documentsPath =[self dirDoc];  
   NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
   NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
//    NSData *data = [NSData dataWithContentsOfFile:testPath];  
//    NSLog(@"文件读取成功: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);  
   NSString *content=[NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];  
   NSLog(@"文件读取成功: %@",content);  
} 
5. 删除文件
//删除文件  单一的指定的文件
-(void)deleteFile{  
   NSString *documentsPath =[self dirDoc];  
   NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
  NSFileManager *fileManager = [NSFileManager defaultManager];  
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];     
   BOOL res=[fileManager removeItemAtPath:testPath error:nil];  
   if (res) {  
       NSLog(@"文件删除成功");  
    }else  
         NSLog(@"文件删除失败");     
    NSLog(@"文件是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO");  
} 

清理缓存Caches,清理路径下的文件

1. 获取缓存文件的大小
-( float )readCacheSize
{
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory , NSUserDomainMask , YES) firstObject];
    return [ self folderSizeAtPath :cachePath];
}


2. 由于缓存文件存在沙箱中,我们可以通过NSFileManager API来实现对缓存文件大小的计算。
// 遍历文件夹获得文件夹大小,返回多少 M
- ( float ) folderSizeAtPath:( 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/( 1024.0 * 1024.0);

}

3. // 计算 单个文件的大小
- ( long long ) fileSizeAtPath:( NSString *) filePath{
    NSFileManager * manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath :filePath]){
        return [[manager attributesOfItemAtPath :filePath error : nil] fileSize];
    }
    return 0;
}

2. 清除缓存
- (void)clearFile
{
    NSString * cachePath = [NSSearchPathForDirectoriesInDomains (NSCachesDirectory , NSUserDomainMask , YES ) firstObject];
    NSArray * files = [[NSFileManager defaultManager ] subpathsAtPath :cachePath];
    //NSLog ( @"cachpath = %@" , cachePath);
    for ( NSString * p in files) {

        NSError * error = nil ;
        //获取文件全路径
        NSString * fileAbsolutePath = [cachePath stringByAppendingPathComponent :p];

        if ([[NSFileManager defaultManager ] fileExistsAtPath :fileAbsolutePath]) {
            [[NSFileManager defaultManager ] removeItemAtPath :fileAbsolutePath error :&error];
        }
    }

   //读取缓存大小
    float cacheSize = [self readCacheSize] *1024;
    self.cacheSize.text = [NSString stringWithFormat:@"%.2fKB",cacheSize];


} 

// 删除文件 路径下的所有文件夹
-(void)clearCache:(NSString *)path{
    NSFileManager *fileManager=[NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        NSArray *childerFiles=[fileManager subpathsAtPath:path];
        for (NSString *fileName in childerFiles) {
            //如有需要,加入条件,过滤掉不想删除的文件
            NSString *absolutePath=[path stringByAppendingPathComponent:fileName];
            [fileManager removeItemAtPath:absolutePath error:nil];
        }
    }
    //    [[SDImageCache sharedImageCache] clearMemory];
}
路径处理
//获取字符串 最后一节的内容 /bick/text/file
[serverFileName lastPathComponent];   // file 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值