IOS文件系统
当开发者第一次启动APP时,ios操作系统就为此app创建了一个文件系统,该文件系统下默认有四个。
分别是:
1、 Documents:存储用户在操作app时产生的数据,此目录下的数据可以通过iCloud(苹果云)进行同步
2、 library:用户偏好设置数据(设置来源,设备锁。。。)通常和此类 NSUserDefaults 搭配使用,此目录下的数据可以通过iCloud进行同步
3、 tmp:存放临时数据,此目录下的数据不会通过iCloud进行同步
4、 app包:开发者不会操作此目录,通常是通过此类NSBundle类来获取包内资源,如工程素材
既然要进行文件读写,那我们就需要得到文件目录路径,得到路径的方法有以下几种:
1、先获取根目录,然后进行字符串拼接
例如:
//获取程序根目录
NSString *homePath = NSHomeDirectory();
//获取根目录下的Documents目录
NSString *documentsPath = [homePath stringByAppendingPathComponent:@"Documents"];
//或者。。。这个与上面方法的区别在于要不要加“/”
documentsPath = [homePath stringByAppendingFormat:@"/Documents"];
2、一般对于Document目录和Library目录推荐下面这种获取路径的方法
//1、第一个参数找到Documents目录,2第二个参数一般都用这一个 3、第三个参数把前面一大串用~省略
documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO) objectAtIndex:0];
//获取library目录路径
NSString * libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
3、获取tmp目录推荐使用下面这个方法
//获取tmp目录
NSString *tmpPath = NSTemporaryDirectory();
下面使用一个例子说明如何使用文件读写
题目:下载一些图片放到tmp目录下的imgs文件夹下,如果有些图片已经下载,那么就不会继续下载
第一步:获取NSFileMAnager单例类,用于文件操作
//个人感觉类似通知中心
NSFileManager *fileManager = [NSFileManager defaultManager];
拼接一个文件夹为Imgs的路径
NSString *imgsDirectory = [tmpPath stringByAppendingPathComponent:@"Imgs"];
第二步:判断本地是否存在某个文件或者文件夹
BOOL isExist = [fileManager fileExistsAtPath:imgsDirectory];
如果不存在就通过这个路径创建一个新的文件夹
NSError *error;
if (!isExist) {
//创建文件夹
//类似到通知中心力注册一个通知,这是到文件系统注册一个文件,通过到文件管理者那里调用 createDirectoryAtPath 创建目录通过路径 这个方法创建一个文件夹
BOOL isSuccess = [fileManager createDirectoryAtPath:imgsDirectory withIntermediateDirectories:YES attributes:nil error:&error];
if (!isSuccess) {
//如果文件创建失败,就将那个打印错错误信息
NSLog(@"error = %@",error.debugDescription);
}
}
第三步:写入文件
定义一个数组来储存要写入的图片URl路径字符串
如下:
NSArray *imgsArray = @[@"http://p0.qhimg.com/dmt/528_351_/t013e453b8c959d9ed8.jpg", @"http://p8.qhimg.com/dmt/235_350_/t013c8e8f64085b9b1a.jpg", @"http://p5.qhimg.com/dmt/235_165_/t01ba76f7974097d574.jpg", @"http://p7.qhimg.com/dmt/235_165_/t01dc724a7d67d1021f.jpg", @"http://p0.qhimg.com/dmt/235_165_/t0180b5a0845da3b84b.jpg",@"http://p8.qhimg.com/dmt/235_350_/t0195bf69f7b893bc80.jpg", @"http://p9.qhimg.com/dmt/235_165_/t014ef7c1bf80dfec45.jpg"];
通过循环获取图片名
//获取图片名字,lastPathComponent方法会去除URL格式的内容,得到图片名。用法祥见官方文档
NSString *imgPath = [imgsArray[i] lastPathComponent];
把目录名+文件名拼接才能将下载文件写入
//得到文件路径字符串
imgPath = [imgsDirectory stringByAppendingPathComponent:imgPath];
判断图片是否已经下载,已经下载就不用重新下载
以下具体不走分解如下:
1、先判断此图片是否已经存在,在文件管理者那里调用 fileExistsAtPath: 方法;
2、不存在就对图片数组中的字符串采用中文格式进行URL编码,把一些中文,%、/、等特殊符号进行编码;
3、将转码后的字符串转换成NSURL,再将NSURL转换成NSData;
4、判断下载的数据data是否为空,不空则写入将数据写入文件,在文件管理者[NSFileManager defaultManager] 那里create一个file 调用createFileAtPath:。。。方法 如右:[[NSFileManager defaultManager] createFileAtPath: contents: attributes:]
if (![fileManager fileExistsAtPath:imgPath]) {
//URL编码
NSString *urlString = [imgsArray[i] stringByAddingPercentEscapesUsingEncoding:4];
//将urlString转换成URL,将URL转换成NSData
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
if (data ==nil) {
NSLog(@"网络有问题") ;
} else {
//将转换成的data写入本地Imgs文件夹
//第一个参数。写入本地时的名字
BOOL isSuccess = [fileManager createFileAtPath:imgPath contents:data attributes:nil];
if (!isSuccess) {
//如果写入不成功,则提示信息
NSLog(@"图片写入不成功,请检查网络设置");
}else {
NSLog(@"图片写入成功");
}
}
}else {
NSLog(@"图片已经下载");
}
}
计算文件大小的方法
//计算文件大小
//在文件管理者那里获得将要计算的所有文件名
NSArray *imgsArray1 = [fileManager subpathsAtPath:imgsDirectory];
//CGFloat 就是double类型而已。。。。。。为毛这么装逼,搞得这么高大上!!!这里count用来计数
CGFloat count = 0.0;
//遍历文件数组
for (NSString *ele in imgsArray1){
//通过拼接得到文件路径,在通过 dataWithContentsOfFile:方法得到NSData
NSData *data1 = [NSData dataWithContentsOfFile:[imgsDirectory stringByAppendingPathComponent:ele]];
count +=data1.length;
}
count = count/1024/1024;
NSLog(@"文件大小:%0.2fM",count);
删除文件的方法
//删除文件
for (NSString *ele in imgsArray1){
//先拼接得到文件路径,再到文件管理者那里删除文件,也可以指定删除文件,这里不做详细描述,改一下很太容易实现,这里只需要知道删除文件用的是 removeItemAtPath: 这个方法。
BOOL isSuccess = [fileManager removeItemAtPath:[imgsDirectory stringByAppendingPathComponent:ele] error:&error];
if (isSuccess) {
NSLog(@"删除成功");
} else {
NSLog(@"删除不成功");
}
}
接下来简单说一下app包
1、先定义一个bundle(bundle英译为束,捆)[NSBundle mainBundle]
2、然后再这个bundle中通过文件名以及类型得到文件路径
3、通过这个路径我们就可以做我们想要实现的很多操作,例如转化成数据,在通过数据转化为image显示出来
//app包:一般放开发的素材
NSBundle *bundle = [NSBundle mainBundle];
NSLog(@"%@",bundle.bundlePath);
NSString* imgPath = [bundle pathForResource:@"t01a14be010eafddbbe" ofType:@"jpg"];
NSData *imgdata = [NSData dataWithContentsOfFile:imgPath];
UIImage *image = [UIImage imageWithData:imgdata];
self.imageView.image = image;