1、应用程序沙盒的基本概念
•iOS中的沙盒(sandbox)机制 iOS应用程序只能对自己创建的文件系统读取文件,这个“独立”“封闭”“安全”的空间,我们称为沙盒。它一般存放着你的程序包文件(可执行文件)、图片、 声音、视频、plist、sqlite数据库以及其他文件。
•每个应用程序都有自己的独立的存储空间(沙盒)
•一般来说应用程序间是不可以相互访问
•模拟器沙盒的位置
/Users/userName/Library/Application Support/iPhone Simulator
•在Lion的系统以后,用户根目录下的资源库文件,默认被设置为隐藏。通过2中方式可以找到该目录
1、直接前往文件
2、在终端输入命令 chflags nohidden ~/
沙盒目录文件的组成以及相关含义
•如下图所示:
![]()
当我们创建我们的应用程序时,在每个沙盒中含有三个文件。分别是
Documents、Library和tmp。
•Documents:一般我们需要持久的数据都放在这个目录中,你可以在当中添加子文 件夹,尤其需要我们注意的是,iTunes备份和恢复的时候,会包括此目录。
•Library:设置程序的默认设置和其它状态信息
•tmp:创建临时文件的目录,当我们的iOS设备重启时,文件会被自动清除
获取沙盒目录
•获取沙盒目录 我们已经对应用程序沙盒有了一个基本的认识,那么我们该如何访问该目录呢?苹果提供了如下方法:
//获取程序的根目录(home)目录
NSString *homePath = NSHomeDirectory();
//获取Documents目录
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *p = [paths lastObject];
NSLog(@"%@",p);
我们已经对应用程序沙盒有了一个基本的认识,那么我们该如何访问该目录呢?苹果提供了如下方法:
//获取Library目录
paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *p = [paths lastObject];
//获取Library中的Cache
NSArray*paths=NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *docPath = [paths lastObject];
//获取tmp路径
NSString *tempPath = NSTemporaryDirectory();
2、NSSTRING类路径处理方法
•文件路径的处理 在某些时候,我们需要对获取的文件目录,做一些特殊处理,已达到所需要的目的。比如有这样一个文件目录,如下:
// 对目录做处理:/Users/apple/testfile.text
NSString *path = @"/Users/apple/testfile.text";
// ------------常用方法如下------------
//获得组成此路径的各个组成部分,结果:(“/”,”Users”,“apple”,”testfile.text”)
- (NSArray *)pathComponents;
//提取路径的最后个组成部分,结果:testfile.text
- (NSString *)lastPathComponent;
// 删除路径的最后 个组成部分,结果:/Users/apple
- (NSString *)stringByDeletingLastPathComponent;
// ------------路径处理的常用方法------------
// 将path添加到现有路径的末尾,结果:/Users/apple/testfile.text/app.text
- (NSString *)stringByAppendingPathComponent:(NSString *)str;
// 取路径最后部分的扩展名,结果:text
- (NSString *)pathExtension;
// 删除路径最后部分的扩展名,结果:/Users/apple/testfile
- (NSString *)stringByDeletingPathExtension;
// 路径最后部分追加扩展名,结果:/Users/apple/testfile.text.jpg
- (NSString *)stringByAppendingPathExtension:(NSString *)str;
3、NSDATA的基本概念
•NSData的基本概念
•NSData是用来包装数据用的
•NSData存数的是二进制数据,这样就屏蔽了数据之间的差异,文本、音频、图像等数据都可以用NSData来存储
•NSMutableData继承NSData类,可以对该对象进行数据修改
// data和string 之间的转换
NSString *s = @"我是字符串";
//string ---> data
NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
//data ---> string
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",str);
4、文件管理常用类和方法
•NSFileManager类NSFileManager类提供了对文件的基本操作类,主要功能如下:
•创建一个新的文件
•从现有文件读取数据
•将数据写入文件
•重新命名文件
•移动文件
•复制文件
•删除文件
•测试文件是否存在
//文件管理常用方法
//创建1个文件并写入数据
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes: (NSDictionary *)attr;
//从1个文件中读取数据
- (NSData *)contentsAtPath:(NSString *)path;
//srcPath路径上的文件移动到 dstPath 路径上, 注意这里的路径是文件路径而不适目录。
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error: (NSError **)error;
//srcPath路径上的文件复制到 dstPath 路径上
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error: (NSError **)error;
// 比较两个文件的内容是否 样
- (BOOL)contentsEqualAtPath:(NSString *)path1 andPath:(NSString *)path2;
// 文件是否存在
- (BOOL)fileExistsAtPath:(NSString *)path;
// 移除文件
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;
//创建文件管理单例
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"holyBible.text"];
NSString *text = @"爱是恒久,忍耐有恩慈";
//将字符串转成NSData类型
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
BOOL success = [fileManager createFileAtPath:path contents:data attributes:nil];
//创建文件夹
NSString *filePath = [path stringByAppendingPathComponent:@"holy Bible.text"];
NSString *content = @"爱是不嫉妒,爱是不自夸";
BOOL success = [fm createFileAtPath:filePath contents:[content dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
//读取文件内容
//NSFileManager实例——读取内容
NSData *fileData = [fileManager contentsAtPath:filePath];
NSString *content = [[NSString alloc] initWithData:fileData
encoding:NSUTF8StringEncoding];
//读取文件内容
//NSData实例——读取内容
NSString *filePath = [path stringByAppendingPathComponent:@"holy Bible.text"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
//读取文件内容
//NSString——读取内容
NSString *filePath = [path stringByAppendingPathComponent:@"holy Bible.text"];
NSString *content = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding error:nil];
//移动文件(重命名)
NSString *toPath = [NSHomeDirectory() stringByAppendingPathComponent:@"hello god/New Testament.text"];
[fm createDirectoryAtPath:[toPath stringByDeletingLastPathComponent]
withIntermediateDirectories:YES attributes:nil error:nil];
NSError *error;
BOOL isSuccess = [fm moveItemAtPath:filePath toPath:toPath error:&error];
//复制文件(重命名)
NSString *copyPath = [NSHomeDirectory() stringByAppendingPathComponent:@"备 份/Old Testament.text"];
[fm createDirectoryAtPath:[copyPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
BOOL success = [fm copyItemAtPath:toPath toPath:copyPath error:nil];
//判断文件是否存在和删除文件
if ([fm fileExistsAtPath:copyPath]) {
if ([fm removeItemAtPath:copyPath error:nil]) {
NSLog(@"remove success");
}
}
//获取文件大小
NSFileManager *fileManager = [NSFileManager defaultManager]; //获得文件的属性字典
NSDictionary *attrDic = [fileManager attributesOfItemAtPath:sourcePath error:nil];
NSNumber *fileSize = [attrDic objectForKey:NSFileSize];
//获取目录文件信息
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *enuPath = [NSHomeDirectory()
stringByAppendingPathComponent:@"Test"];
NSDirectoryEnumerator *dirEnum =
[fileManager enumeratorAtPath:enuPath];
NSString *path = nil;
while ((path = [dirEnum nextObject]) != nil) {
NSLog(@"%@",path);
}
5、数据持久性——属性列表化
•概念:iOS数据持久性的一种方式,使用方便简单快键
//字符串
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"String.plist"];
NSString *content = @"爱是恒久";
[content writeToFile:path
atomically:YES
encoding:NSUTF8StringEncoding error:nil];
//数组
NSString *path = [NSHomeDirectory()
stringByAppendingPathComponent:@"Array.plist"];
NSArray *array = @[@123, @789, @"123", @"000"];
[array writeToFile:path atomically:YES];
//字典
NSString *path = [NSHomeDirectory()
stringByAppendingPathComponent:@"Dic.plist"];
NSDictionary *dic = @{@"first" : @1, @"second" : @2, @"third" : @[@123,@456]};
[dic writeToFile:path atomically:YES];
数组、字典只能将Bool、NSNumber、NSString、NSData、NSDate、 NSArray、NSDictionary 写入属性列表plist文件
6、读取文件类和常用方法
•NSFileHandle
•NSFileManager类主要对文件的操作(删除、修改、移动、复制等等)
•NSFileHandle类主要对文件内容进行读取和写入操作
•NSFileHandle处理文件的步骤:•创建一个NSFileHandle对象
•对打开的文件进行I/O操作
•关闭文件•可以使用NSFileHandle做文件的断点续传
•NSFileHandle 只可以读写文件,不能创建文件,创建文件使用NSFileManager
•常用处理方法
+ (id)fileHandleForReadingAtPath:(NSString *)path; // 打开1个文件准备读取
+ (id)fileHandleForWritingAtPath:(NSString *)path; // 打开1个文件准备写入
+ (id)fileHandleForUpdatingAtPath:(NSString *)path; // 打开1个文件准备更新 (读取、更新)
- (NSData *)availableData; // 从设备或通道返回可用的数据
- (NSData *)readDataToEndOfFile; // 从当前的节点读取到文件末尾
- (NSData *)readDataOfLength:(NSUInteger)length; // 从当前节点开始读取指定的长度数据
- (unsigned long long)offsetInFile; // 获取当前文件的偏移量
- (void)seekToFileOffset:(unsigned long long)offset; // 跳到指定文件的偏移量
- (void)truncateFileAtOffset:(unsigned long long)offset; // 将文件的长度设 置为offset字节
- (void)closeFile; // 关闭文件
//向文件追加数据
NSString *homePath = NSHomeDirectory();
NSString *sourcePath = [homePath
stringByAppendingPathComponent:@"testfile.text"];
NSFileHandle *fileHandle = [NSFileHandle
fileHandleForUpdatingAtPath:sourcePath];
// 将节点跳到文件末尾
[fileHandle seekToEndOfFile];
NSString *str = @"追加的数据";
NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding];
// 追加写入数据
[fileHandle writeData:stringData];
[fileHandle closeFile];
//定位数据
NSFileManager *fm = [NSFileManager defaultManager];
NSString *content = @"abcdefghijklmn";
[fm createFileAtPath:path contents:[content
dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
// 获得数据长度
NSUInteger length = [[fileHandle availableData] length];
// 偏移量但文件的1半
[fileHandle seekToFileOffset:length/2];
// 从1半开始将数据读到文件最后
NSData *data = [fileHandle readDataToEndOfFile];
[fileHandle closeFile];
//复制文件
//输入文件、输出文件
NSFileHandle *infile, *outfile;
//读取的缓冲数据
NSData *buffer;
NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *homePath = NSHomeDirectory();
//源文件路径
NSString *sourcePath = [homePath stringByAppendingPathComponent:@"testfile.text"];
//输出文件路径
NSString *outPath = [homePath
stringByAppendingPathComponent:@"outfile.text"];
//创建输出文件
BOOL success = [fileManager createFileAtPath:outPath contents:nil attributes:nil];
if (!success) {
return NO;
}
//创建读取源路径文件
infile = [NSFileHandle fileHandleForReadingAtPath:sourcePath];
if (infile == nil) {
return NO;
}
//创建并打开要输出的文件
outfile = [NSFileHandle fileHandleForWritingAtPath:outPath];
if (outfile == nil) {
return NO;
}
//将输出文件的长度设为0
[outfile truncateFileAtOffset:0];
//读取数据
buffer = [infile readDataToEndOfFile];
//写入输入
[outfile writeData:buffer];
//关闭写入、输入文件
[infile closeFile];
[outfile closeFile];
大文件的复制
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString *homePath = NSHomeDirectory();
//要复制的源文件路径
NSString *srcPath = [homePath stringByAppendingPathComponent:@"Foundation_API.pdf"];
//目标文件路径
NSString *tagetPath = [homePath stringByAppendingPathComponent:@"Foundation_API_bak.pdf"];
NSFileManager *fileManager = [NSFileManager defaultManager];
//创建目标文件
BOOL success = [fileManager createFileAtPath:tagetPath contents:nil attributes:nil];
if (success) {
NSLog(@"create success");
}
//读取文件对象
NSFileHandle *inFile = [NSFileHandle fileHandleForReadingAtPath:srcPath];
//写文件对象
NSFileHandle *outFile = [NSFileHandle fileHandleForWritingAtPath:tagetPath];
//获取文件的属性
NSDictionary *fileAttri = [fileManager attributesOfItemAtPath:srcPath error:nil];
//获取文件的大小
NSNumber *fileSizeNum = [fileAttri objectForKey:NSFileSize];
BOOL isEnd = YES;
NSInteger readSize = 0; //已经读取的文件大小
NSInteger fileSize = [fileSizeNum longValue]; //文件的总大小
NSAutoreleasePool *pool = nil;
int n = 0;
NSLog(@"开始复制....");
while (isEnd) {
if (n % 10 == 0) {
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
//计算剩下未读文件的大小
NSInteger subLeng = fileSize - readSize;
NSData *data = nil;
//如果剩余文件大小小于5000,则将剩下的数据全都读完,并且不再循环读取了
if (subLeng < 5000) {
isEnd = NO; //跳出循环
data = [inFile readDataToEndOfFile]; //读取剩下的数据
} else {
//读取5000个字节
data = [inFile readDataOfLength:5000];
//累加读取的大小
readSize += 5000;
[inFile seekToFileOffset:readSize];
}
//写入数据
[outFile writeData:data];
n++;
}
//关闭文件
[outFile closeFile];
NSLog(@"文件复制成功");
}
return 0;
}