移动开发(IOS) – Objective-C-07-文件管理

移动开发(IOS) – Objective-C-07-文件管理

By docoder in 博客学习 on 2014/05/28

ios-objective-c-7

1.沙盒

1.1.iOS 中每个 App 应用程序都有一个单独封闭的文件夹,这个文件夹称为沙盒 ( sandbox )

1.2.沙盒目录用来存放 App 的本地文件,例如:音频、视频、图片文件 …

1.3.当前 App 应用程序没权限访问其他 App 的沙盒。(更安全)

1.4.应用程序包:(Bundle)包含了所有的资源文件和可执行文件。

1.5.沙盒目录中有如下子目录:

1.5.1.Documents 存放长期使用的文件。保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。

1.5.2.Library 系统存放文件。Library/Caches, 保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积较大、不需要备份的非重要数据。Library/Preference:保存应用的所有偏好设置,iOS的设置应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录。

1.5.3.tmp 临时文件,App 重启时,该目录下的文件清空。保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也有可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。

2.NSString 处理文件路径

2.1.OC里的文件路径通过NSString来描述。

2.2.获取沙盒路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//沙盒的主⺫录
NSString *homePath = NSHomeDirectory ();
 
/***获取Documents⺫录***/
//1.
// NSUserDomainMask 代表从用户文件夹下找
// YES 代表展开路径中的波浪字符“~”
NSArray *documents = NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES );
// 只有一个匹配目录,所以这个集合里面只有一个元素
NSString *doc = documents[0];
//2.
//使用字符串拼接的方式获取
//不建议采用字符串拼接的方式获取目录,因为新版本的操作系统可能会修改默认目录名称
NSString *documents = [homePath stringByAppendingPathComponent: @"Documents" ];
 
/***获取Cache目录***/
NSArray *caches = NSSearchPathForDirectoriesInDomains ( NSCachesDirectory , NSUserDomainMask , YES );
NSString *cache = caches[0];
 
/***获取Library⺫录***/
NSString *library = [homePath stringByAppendingPathComponent: @"Library" ];
 
/***Preferences目录***/
//通过NSUserDefaults类存取该目录下的设置信息
NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults];
[defaults setObject: @"docoder" forKey: @"userName" ];
[defaults setFloat:18.0f forKey: @"fontSize" ];
[defaults setBool: YES forKey: @"autoLogin" ];
// 读取系统偏好
NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults];
NSString *userName = [defaults objectForKey: @"userName" ];
float fontSize = [defaults floatForKey: @"fontSize" ];
BOOL autoLogin = [defaults floatForKey: @"autoLogin" ];
//注意:UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘,应用程序就终止了。
//出现以上问题,可以通过调用synchornize方法强制写入:
[defaults synchronize];
 
/***获取tmp⺫录***/
NSString *tmpDir = NSTemporaryDirectory ();

2.3.NSString可以对路径做一些处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//演⽰路径
NSString *path = @"/Users/username/file.txt" ;
//1.获取路径的组成部分 结果: (“/”,”Users”, “username”, “file.txt”)
NSArray *components = [path pathComponents];
//2.路径的最后一个组成部分 结果: file.txt
NSString *lastName = [path lastPathComponent];
//3.追加⽂件或⺫录 结果: /Users/username/file.txt/app.txt
NSString *filePath = [path stringByAppendingPathComponent: @"app.txt" ];
//4.删除最后部分的组成部分 结果: /Users/username
NSString *filePath = [path stringByDeletingLastPathComponent];
//5.取路径最后部分的扩展名 结果: txt
NSString *extName = [path pathExtension];
//6.追加扩展名 结果: /Users/username/file.txt.jpg
NSString *filePath = [path stringByAppendingPathExtension: @"jpg" ];

3.NSFileManager

3.1.NSFileManager 主要对文件进行管理, 具有:创建文件,复制文件,删除文件,剪切文件的功能。

3.2.NSFileManager 为单例,不能用 alloc 创建:

1
2
//创建 NSFileManager 对象
NSFileManager *fileManager = [ NSFileManager defaultManager];

3.3.常用方法:

1
2
3
4
5
6
7
8
9
10
11
12
//创建一个⽂件并写入数据
- ( BOOL )createFileAtPath:( NSString *)path contents:( NSData *)data attributes:( NSDictionary *)attr;
//从⼀个文件中读取数据
- ( 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 )fileExistsAtPath:( NSString *)path;
// 移除⽂件
- ( BOOL )removeItemAtPath:( NSString *)path error:( NSError **)error;

3.4.创建文件:

1
2
3
4
5
6
7
8
9
//创建 NSFileManager 对象
NSFileManager *fileManager = [ NSFileManager defaultManager];
NSString *homePath = NSHomeDirectory ();
NSString *path = [homePath stringByAppendingPathComponent: @"file.txt" ];
NSString *text = @"docoder" ;
//将字符串转成NSData类型
NSData *data = 1;
//写⼊文件
BOOL success = [fileManager createFileAtPath:path contents:data attributes: nil ];

3.5.读取文件

1
2
3
4
5
6
//创建 NSFileManager 对象
NSFileManager *fileManager = [ NSFileManager defaultManager];
//根据路径读取文件
NSData *fileData = [fileManager contentsAtPath:filePath];
//将NSData转NSString
NSString *content = [[ NSString alloc] initWithData:fileData encoding: NSUTF8StringEncoding ];

3.6.剪切、复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NSString *homePath = NSHomeDirectory ();
//源⽂件路径
NSString *srcPath = [homePath stringByAppendingPathComponent: @"file.txt" ];
//目标路径
NSString *toPath = [homePath stringByAppendingPathComponent: @"Documents/file.txt" ];
 
NSError *error;
//剪切(移动)文件
//将srcPath路径的文件剪切(移动)到toPath路径
BOOL isSuccess = [fm moveItemAtPath:srcPath toPath:toPath error:&error];
if (!isSuccess){
     NSLog ( @"失败:%@" ,error);
}
//复制文件
//将srcPath路径的⽂件复制到toPath路径
BOOL success = [fm copyItemAtPath:srcPath toPath:toPath error: nil ];

3.7.删除文件

1
2
3
4
5
6
7
8
9
//判断⽂件是否存在
BOOL isExist = [fm fileExistsAtPath: path];
if (isExist) {
     //删除⽂件
     BOOL success = [fm removeItemAtPath:path error: nil ];
     if (success) {
         NSLog ( @"remove success" );
     }
}

3.8.获取文件大小

3.8.1.通过读取文件属性获得:

1
2
3
4
5
NSFileManager *fileManager = [ NSFileManager defaultManager];
//获得文件的属性字典
NSDictionary *attrDic = [fileManager attributesOfItemAtPath:path error: nil ];
//获取⽂件⼤小
NSNumber *fileSize = [attrDic objectForKey: NSFileSize ];

3.8.2.计算获得 (此方法如果读取大文件会很占有内存,不建议使用):

1
2
3
NSFileManager *fileManager = [ NSFileManager defaultManager];
NSData *data = [fileManager contentsAtPath:path];
NSInteger len=data.length;

4.writeToFile 写文件

4.1.数组、字典、字符串、NSData 都是容纳数据的,他们都有一个 writeToFile 方法, 将数据写入文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSString *string = @"docoder" ;
NSError *error;
 
//atomically:YES,表示写成功后(会写入到临时文件中)再覆盖文件,若写入失败,则不会覆盖文件,这样更安全。
BOOL isSuccess = [string writeToFile:path atomically: YES encoding: NSUTF8StringEncoding error: &error]
 
if (!isSuccess){
     NSLog ( @"写入失败:%@" ,error);
} else {
     NSLog ( @"写入成功" );
}
 
NSString *backString = [ NSString stringWithContentsOfFile:path encoding: NSUTF8StringEncoding error: nil ]
NSLog ( @"取回字符串:%@" ,backString);

4.2.数组写入文件:

1
2
3
4
5
6
7
8
9
10
NSString *s1 = @"zhangsan" ;
NSString *s2 = @"lisi" ;
NSArray *array = [ NSArray arrayWithObjects:s1,s2, nil ];
//将数组中的数据写⼊文件
[array writeToFile:path atomically: YES ];
 
//取回写入的数组(alloc)
NSArray *backArray=[[ NSArray alloc] initWithContentsOfFile:path];
//取回写入的数组(类方法)
NSArray *backArray = [ NSArray arrayWithContentsOfFile:path];

4.3.数组只能将如下数据类型写入文件,如果包含其他对象,将写入失败。

NSNumber NSString NSData NSDate NSArray NSDictionary

4.4.数组、字典写入的文件叫属性列表 (plist) 文件 (一种XML格式的文件),可以用xcode打开编辑。

4.5.如果所指定保存文件的路径不存在,写入文件方法不会报错,文件也不会被保存。

4.6.其他格式数据的保存:

4.6.1.NSString , 保存时需要自定字符串编码。

4.6.2.UIImage , 注意UIImage无法写入文件,需要使用NSData数据类型进行中转,NSData可以将任何类型的文件,以二进制格式存储。

1
2
// 生成图像数据
NSData *data = UIImagePNGRepresentation(image);

5.NSFileHandle

5.1.NSFileManager 主要对文件进行 (删除、修改、移动、复制)。NSFileHandle 主要是对文件的内容进行读取和写入操作。

5.2.NSFileHandle 不能创建文件,只能对现有文件进行读写,并且可以通过文件偏移量来定位读写。

5.3.常用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//创建NSFileHandle,并且打开文件准备读取
+ ( id )fileHandleForReadingAtPath:( NSString *)path;
//创建NSFileHandle,并且打开⽂件准备写入
+ ( id )fileHandleForWritingAtPath:( NSString *)path;
//创建NSFileHandle,并且打开文件准备写入或读取
+ ( id )fileHandleForUpdatingAtPath:( NSString *)path;
//读取文件全部数据
- ( NSData *)availableData;
//写⼊数据
- ( void )writeData:( NSData *)data;
 
// 获取当前⽂件的偏移量
- (unsigned long long )offsetInFile;
// 跳到指定⽂件的偏移量
- ( void )seekToFileOffset:(unsigned long long )offset;
// 使偏移量跳到文件末尾
- (unsigned long long )seekToEndOfFile;
// 从当前偏移量读取到文件末尾
- ( NSData *)readDataToEndOfFile;
// 从当前偏移量开始读取指定的长度数据
- ( NSData *)readDataOfLength:( NSUInteger )length;

5.4.向文件追加数据:

1
2
3
4
5
6
7
8
9
10
11
NSString *sourcePath = [ NSHomeDirectory () stringByAppendingPathComponent: @"file.txt" ];
//创建可读写的 NSFileHandle 对象
NSFileHandle *fileHandle = [ NSFileHandle fileHandleForUpdatingAtPath:sourcePath];
//将偏移量跳到文件末尾
[fileHandle seekToEndOfFile];
NSString *str = @"追加的数据" ;
NSData *stringData = [str dataUsingEncoding: NSUTF8StringEncoding ];
//写⼊数据
[fileHandle writeData:stringData];
//关闭⽂件
[fileHandle closeFile];

5.5.定位偏移量读取:

1
2
3
4
5
6
7
8
9
10
11
NSFileManager *fileManager = [ NSFileManager defaultManager];
NSDictionary *fileAttr = [fileManager attributesOfItemAtPath:filePath error: nil ];
NSNumber *filesize = [fileAttr objectForKey: NSFileSize ];
long length = [filesize longValue];
NSFileHandle *fileHandle = [ NSFileHandle fileHandleForReadingAtPath:path];
// 将偏移量定位到⽂件⻓度的一半
[fileHandle seekToFileOffset:length/2];
// 从当前偏移量读到⽂件最后
NSData *data = [fileHandle readDataToEndOfFile];
// 关闭⽂件
[fileHandle closeFile];

5.6.使用NSFileHandle实现复制文件功能:

此方法将全部数据一次读,一次写,若文件很大,会很占内存,可以将其改为分批读写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
NSFileManager *fileManager = [ NSFileManager defaultManager];
NSString *homePath = NSHomeDirectory ();
//源⽂件路径
NSString *sourcePath = [homePath stringByAppendingPathComponent: @"srcfile.txt" ];
//输出⽂件路径
NSString *outPath = [homePath stringByAppendingPathComponent: @"outfile.txt" ];
//创建输出文件
BOOL success = [fileManager createFileAtPath:outPath contents: nil attributes: nil ];
if (!success) {
     NSLog ( @"创建⽂件失败" );
}
//创建NSFileHandle,用于读取源路径文件
NSFileHandle *infile = [ NSFileHandle fileHandleForReadingAtPath:sourcePath];
if (infile == nil ) {
     NSLog ( @"打开失败:路径:%@" ,sourcePath);
}
//创建NSFileHandle,⽤于将数据写入该文件
NSFileHandle *outfile = [ NSFileHandle fileHandleForWritingAtPath:outPath];
if (outfile == nil ) {
     NSLog ( @"打开失败:路径:%@" ,outPath);
}
//从当前偏移量读取文件剩下的所有数据
NSData *buffer = [infile availableData];
//将数据写⼊输出文件
[outfile writeData:buffer];
//关闭写入、输入⽂件
[infile closeFile];
[outfile closeFile];

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值