博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS进阶第一节 数据读写之文件读写
阅读量:5132 次
发布时间:2019-06-13

本文共 11295 字,大约阅读时间需要 37 分钟。

 

一、沙盒机制

  1>. 每一个iOS程序都会问自己创建一个文件系统目录(文件夹),这个独立、封闭、安全的空间,叫做沙盒。

  注:①. 每一个应用程序都会拥有一个应用程序沙盒

    ②. 应用程序沙盒就是一个文件系统目录

  2>. 沙盒机制的特点

  ①. 沙盒是一种安全体系

  ②. 所有的非代码文件都保存在沙盒中,比如声音、图片、属性列表(plist)、sqlite数据库和文本文件等

  ③. 每个应用程序的活动范围都限定在自己的沙盒里,不能跨越沙盒去访问别的应用程序沙盒中的内容(iOS8已经部分开放)

  ④. 应用程序向外请求或接受数据都需要经过权限认证

  3>. 每个应用程序沙盒中都有三个文件夹(Documents、library、tmp)

  • Documents:保存应用程序运行时生成的需要持久化的数据,iTunes会自动备份该目录
  • Library/Caches:存放缓存文件,iTunes不会自动备份此目录,此目录下的文件不会在应用退出删除;一般存储体积加大,不是特别重要的资源。
  • Library/Preferences:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录
  • tmp:保存应用运行时所需的临时数据, 使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也有可能会清除该目录下的文件,iTunes不会同步该目录。iPhone重启时,该目录下的文件会被删除。

  4>. 获取应用程序及三个文件目录的代码:

// 获取当前应用程序的沙盒根目录    NSString *rootPath = NSHomeDirectory();    NSLog(@"rootPath is %@", rootPath);        // 定位根目录下的所有文件的目录    // 1、Documents    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];    NSLog(@"documentsPath is %@", documentsPath);    //    NSString *documentsPath1 = [rootPath stringByAppendingString:@"/Documents"];    NSString *documentsPath1 = [rootPath stringByAppendingPathComponent:@"Documents"];    NSLog(@"documentsPath1 is %@", documentsPath1);        // 2、Library    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];    NSLog(@"libraryPath is %@", libraryPath);    // 3、Library之Caches    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];    NSLog(@"cachePath is %@", cachePath);    // 4、library之Preferences    NSString *preferencesPath = [libraryPath stringByAppendingPathComponent:@"preferences"];    NSLog(@"preferencesPath is %@", preferencesPath);    // 5、tmp    NSString *tmpPath = NSTemporaryDirectory();    NSLog(@"tmpPath is %@", tmpPath);

 

 二、简单对象的读写(I/O)操作

  1>. iOS提供了4种类型的数据可以直接进行文件存取:

  NSString/NSMutableString(字符串)

  NSArray/NSMutableArray(数组)

  NSDictionary/NSMutableDictionary(字典)

  NSData/NSMutableData(数据)

  注:数组和字典中元素对象的类型,也必须是上述四种,否则不能直接写入文件。

  2>. 相应的读写代码:

// 字符串写入沙盒    // 在Ducuments下面创建一个文本路径,假设文本名称为bada.txt    NSString *txtPath = [documentsPath stringByAppendingPathComponent:@"bada.txt"]; // 此时仅存在路径,文件并没有真实存在    NSString *string = @"中二洪荒巴达之力";        // 字符串写入时执行的方法    [string writeToFile:txtPath atomically:YES encoding:NSUTF8StringEncoding error:nil];    NSLog(@"txtxPath is %@", txtPath);        // 字符串读取的方法    NSString *resultString = [NSString stringWithContentsOfFile:txtPath encoding:NSUTF8StringEncoding error:nil];    NSLog(@"resultString is %@", resultString);        // 数组写入文件    // 创建一个存储数组文件路径    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"girl.txt"];    NSArray *array = @[@"姜丽玲", @"王六六", @"胡洁佩", @"戴苗苗", @"莫大宝", @"朱珍洁", @"秋香"];        // 数组写入文件的方法    [array writeToFile:filePath atomically:YES];    NSLog(@"filePath is %@", filePath);        // 从文件中间读取数组的方法    NSArray *resultArray = [NSArray arrayWithContentsOfFile:filePath];    NSLog(@"%@", resultArray[1]);        // 字典写入文件    // 创建一个存储字典文件路径    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"love.txt"];    NSDictionary *dictionary = @{
@"巴达":@"秋香", @"张不慌":@"王六六"}; // 字典写入文件的方法 [dictionary writeToFile:filePath atomically:YES]; NSLog(@"filePath is %@", filePath); // 从文件中间读取字典的方法 NSDictionary *resultDictionary = [NSDictionary dictionaryWithContentsOfFile:filePath]; NSLog(@"%@", resultDictionary); // NSData写入文件 // 创建一个存放NSData数据的路径 NSString *filePath = [documentsPath stringByAppendingPathComponent:@"baby.txt"]; // 得到一个UIImage对象 UIImage *image = [UIImage imageNamed:@"5"]; // 将UIImage对象转换成NSData对象 NSData *data = UIImagePNGRepresentation(image); // data写入文件的方法 [data writeToFile:filePath atomically:YES]; NSLog(@"filePath is %@", filePath); // 从文件读取存储的NSData数据 NSData *resultData = [NSData dataWithContentsOfFile:filePath]; // 将得到的NSData数据转换成原有的图片对象 UIImage *resultImage = [UIImage imageWithData:resultData]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; imageView.image = resultImage; [self.view addSubview:imageView];   注:每一种类型单独执行!

 

三、文件管理器(NSFileManager)和文件对接器(NSFileHandle)

  1>. 两者的区别:

  文件管理器主要是对文件进行的操作(创建、删除、改名等)以及文件信息的获取;

  而文件连接器主要是对文件内容进行读取和写入操作。

  2>. 文件管理器(NSFileManager)应用

  ①. 创建文件及简单操作代码:

- (IBAction)createFile:(id)sender {    // 得到Documents路径    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];    // 创建一个文件路径    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"qiuxiang.txt"];    // 创建文件需要一个文件管理对象    NSFileManager *fileManager = [NSFileManager defaultManager];    // 创建文件    [fileManager createFileAtPath:filePath contents:[@"bada" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];    NSLog(@"%@", filePath);        // 获取某个文件或者某个文件夹的大小    NSDictionary *dic = [fileManager attributesOfItemAtPath:filePath error:nil];    NSLog(@"%@", dic);    NSNumber *number = [dic objectForKey:NSFileSize];    NSLog(@"%@", number);    }

  ②. 创建目录(文件夹)代码:

- (IBAction)createDirectory:(id)sender {    // 找到caches的路径    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];    // 创建的文件夹的路径    NSString *directoryPath = [cachesPath stringByAppendingPathComponent:@"downlondImages"];    // 创建文件需要一个管理对象    NSFileManager *fileManager = [NSFileManager defaultManager];    // 创建文件夹    [fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:nil];    NSLog(@"%@", directoryPath);    }

  ③. 应用实例代码:

/*  在Documents文件夹下,创建一个文件夹(path),在该文件夹下创建一个文件(test.txt),将一个图片对象存入到该文件中, 然后在Caches文件夹下创建一个文件夹名为"testDirectroy",将test.txt文件移动到这个文件夹下.   */- (IBAction)test1:(id)sender {    // 在Documents文件夹下,创建一个文件夹(path),在该文件夹下创建一个文件(test.txt),将一个图片对象存入到该文件中    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];    NSString *path = [docPath stringByAppendingPathComponent:@"path"];    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];    NSString *testPath = [path stringByAppendingPathComponent:@"test.txt"];    UIImage *image = [UIImage imageNamed:@"5"];    NSData *data = UIImagePNGRepresentation(image);    [fileManager createFileAtPath:testPath contents:data attributes:nil];    NSLog(@"%@",testPath);        //然后在Caches文件夹下创建一个文件夹名为"testDirectroy"    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];    NSString *dirPath = [cachePath stringByAppendingPathComponent:@"testDirectroy"];    [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];    NSLog(@"dirPath is %@",dirPath);        //移动    NSString *desPath = [dirPath stringByAppendingPathComponent:@"baby.txt"];    [fileManager moveItemAtPath:testPath toPath:desPath error:nil];}

  3>. 文件对接器(NSFileHandle)

  ①. NSFileHandle是非常基础的只针对文件内容的操作(写入、读取、根性),是把NSData通过连接器一个字节一个字节的写入/读取文件(NSData <——> NSFileHandle <——> 文件)。

  ②. 使用场景:对文件内容进行局部的修改、追加内容。

  ③. 使用步骤:1). 文件对接并获取一个NSFileHandle对象;  

          2). 读写操作;

          3).关闭对接。

  注:NSFileHandle类并没有提供创建文件的功能,必须使用NSFileManager的方法来创建文件,因此,在使用NSFileHandle的特有方法时,到要保证文件已经存在,否则返回nil。

  4>. 应用实例代码:

/* 练习要求:从一个文件中指定的位置开始追加内容 提示:   1、在documents目录下创建一个test.txt文件,文件中的内容为"abcdefg"   2、从文件偏移量为3那个位置开始追加内容"1234" */- (void)change {    // 获取Documents路径    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];    // 创建文件路径    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"test.txt"];    // 使用文件管理对象创建文件    NSFileManager *fileManager = [NSFileManager defaultManager];    [fileManager createFileAtPath:filePath contents:[@"abcdefg" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];    // 创建文件对接对象    NSFileHandle *habdle = [NSFileHandle fileHandleForUpdatingAtPath:filePath]; // 文件对接对象此时针对文件,既可以读取,也可以写入    // 将偏移量挪到3的文字    [habdle seekToFileOffset:3];    // 写入数据    [habdle writeData:[@"1234" dataUsingEncoding:NSUTF8StringEncoding]];    // 执行完后关闭文件    [habdle closeFile];        NSLog(@"%@", filePath);   }

 

四、复杂对象的读写(I/O)操作

  1>. 复杂对象就是在Foundation框架内不存在的数据类,

        如:自定义的Person类无法在程序内通过 writerToFile: 这个方法写入文件内。

  2>. 复杂对象只能通过 将复杂对象转换为NSData(这个步骤就是归档),然后再通过 writerToFile: 方法写入文件

        来进行数据持久化

  3>. 从文件中读取复杂对象是 从文件中读取NSData数据,然后再将NSData转换为复杂对象(这个过程就是反归档)。

 

  注:①. 复杂对象写入文件的过程:复杂对象 —> 归档 —> NSData —> writeToFile;

    ②. 从文件中读取复杂对象的过程:读取文件   NSData   反归档   复杂对象。

  4>. 归档和反归档实例(以Person对象为例)

  ①. 首先,要遵守NSCoding协议:

@interface Person : NSObject 
@property (copy, nonatomic) NSString *name;@property (copy, nonatomic) NSString *age;@property (copy, nonatomic) NSString *gender; - (instancetype)initWithName:(NSString *)name age:(NSString *)age gender:(NSString *)gender; @end

  ②. 其次,实现协议里的两个方法:

// 对Person对象进行归档时,此方法执行。 // 对Person中想要进行归档的所有属性,进行序列化操作 - (void)encodeWithCoder:(NSCoder *)aCoder {    [aCoder encodeObject:self.name forKey:@"name"];    [aCoder encodeObject:self.age forKey:@"age"];    [aCoder encodeObject:self.gender forKey:@"gender"];}
// 对Person对象进行反归档时,此方法执行。 // 创建一个新的Person对象,所有属性都是通过反序列化得到的 - (id)initWithCoder:(NSCoder *)aDecoder {
    NSString *name = [aDecoder decodeObjectForKey:@"name"];     NSString *age = [aDecoder decodeObjectForKey:@"age"];     NSString *gender = [aDecoder decodeObjectForKey:@"gender"];     return [self initWithName:name age:age gender:gender]; }

  ③. 具体操作代码:

// 归档- (IBAction)archive:(id)sender {        // 创建两个人    Person *bada = [[Person alloc] initWithName:@"bada" age:@"22" gender:@"男"];    Person *qiuxiang = [[Person alloc] initWithName:@"qiuxiang" age:@"18" gender:@"女"];        // 获取Documents路径    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];    // iOS中的归档类是NSKeyedArchiver,这个类的作用是将复杂对象转换成NSData对象    // 创建一个可变数据对象    NSMutableData *mData = [NSMutableData data];    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:mData];        // 归档时要给归档对象加标记    [archiver encodeObject:bada forKey:@"yadang"];    [archiver encodeObject:qiuxiang forKey:@"xiawa"];        [archiver finishEncoding]; // 结束归档,不管还有多少未归档的归档对象,都不会执行归档操作        // 将数据写入文件    // 创建文件路径    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"bada.qiuxiang"];    [mData writeToFile:filePath atomically:YES];}// 反归档- (IBAction)unArchiver:(id)sender {        // 获取到存放数据的路径    // 获取Documents路径    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"bada.qiuxiang"];    // 获取NSData对象    NSData *data = [NSData dataWithContentsOfFile:filePath];        // iOS中的解档类是NSKeyedUnarchiver,TA的作用是讲NSData对象还原成原本的复杂对象    NSKeyedUnarchiver *unarchibver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];    // 解档    Person *person = [unarchibver decodeObjectForKey:@"yadang"];        NSLog(@"name is %@, age is %@, gender is %@", person.name, person.age, person.gender);   }

 

转载于:https://www.cnblogs.com/hyl2012/p/5223136.html

你可能感兴趣的文章
2017-10-06-构建之法:现代软件工程-阅读笔记
查看>>
fireFox IE刷新不提示
查看>>
javaweb
查看>>
C语言 · 查找整数 · 基础练习
查看>>
开源智能英文单词提取翻译工具(C#)
查看>>
Java新帮派——数组
查看>>
Python sys模块
查看>>
UML类图
查看>>
SharedPreferences封装类SPUtils
查看>>
兄弟选择器+否定伪类
查看>>
多媒体容器格式概述①
查看>>
【线性表6】线性表的链式实现:双向链表
查看>>
Java RMI VS TCP Socket
查看>>
python函数式编程之返回函数、匿名函数、装饰器、偏函数学习
查看>>
你必须知道的28个HTML5特征、窍门和技术
查看>>
Obj文件分析与读取
查看>>
算法之旅 | 冒泡排序法
查看>>
JavaScript学习二-----JS对象一
查看>>
socket
查看>>
docker 运行镜像
查看>>