NSFileManager
NSFileManager是iOS中的文件管理类
一、生成一个路径
这是NSString的API,在string的基础上加上一个path名,生成一个路径
注意:这个函数自动在前一个path的后面加上 "/" 如果后面的一个path的文件名里有 "/" 则会将 "/" 去除
//stringByAppendingPathComponent 函数自动在前一个path的后面加上 "/" 如果后面的一个path的文件名里有 "/" 则会将 "/" 去除
NSString *filePath = [self.document stringByAppendingPathComponent:@"hhhh"];
filePath = [self.document stringByAppendingPathComponent:@"/hhhh"];
filePath = [NSString stringWithFormat:@"%@%@", self.document, @"hhhh"];
打印结果:
(lldb) po filePath /Users/huangshan/Library/Developer/CoreSimulator/Devices/681E5EB6-4A22-4512-AA8F-27E033EBF5F6/data/Containers/Data/Application/99C274AC-5228-43B6-A0BA-684A88675120/Documents/hhhh
(lldb) po filePath /Users/huangshan/Library/Developer/CoreSimulator/Devices/681E5EB6-4A22-4512-AA8F-27E033EBF5F6/data/Containers/Data/Application/99C274AC-5228-43B6-A0BA-684A88675120/Documents/hhhh
(lldb) po filePath /Users/huangshan/Library/Developer/CoreSimulator/Devices/681E5EB6-4A22-4512-AA8F-27E033EBF5F6/data/Containers/Data/Application/99C274AC-5228-43B6-A0BA-684A88675120/Documentshhhh
二、判断文件是否存在
- filePath:文件或文件夹路径
[self.fileManager fileExistsAtPath:filePath];
三、创建文件夹
在指定的目录下创建文件夹,如果该文件夹存在,则不创建
- filePath:文件夹的路径
- IntermediateDirectories:是否创建中间文件夹,YES会创建中间文件夹,NO不会创建中间文件件(具体看代码demo2)
- attributes:文件夹的属性(后面详细说明)
[self.fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
四、创建文件
在指定的目录下创建文件,如果该文件名(文件名包括了后缀在内,比如test1和test1.html是两个文件)存在,则将这个文件删除,然后再创建;如果文件名不存在,则直接创建
此时这个文件的attributes
信息全部更改,创建时间变成当前时间,修改时间变成当前时间
- path:文件的路径
- contents:文件的二进制内容(NSData)
- attributes:文件的属性(后面详细说明)
如果path前面的路径(即/path之前的路径)存在,只是文件不存在,则会生成一个文件,然后将NSData写入,如果path所在的路径的中间的路径不存在,则不会写入文件
[self.fileManager createFileAtPath:test1Path contents:nil attributes:nil];
五、移除文件
- path:文件的路径
- error:错误报告
[self.fileManager removeItemAtPath:test1Path error:nil];
六、获得子文件或文件夹的名字
- filePath:文件的路径
NSArray *subArray = [self.fileManager subpathsAtPath:filePath];
打印结果:
(lldb) po subArray
<__NSArrayM 0x7fd9e85ab530>(
folder,
test0,
test1,
test2,
test3,
test4
)
七、获取文件属性(attributes)
获取文件或者文件夹的属性
- path:文件的路径
- error:错误报告
NSDictionary *attr = [self.fileManager attributesOfItemAtPath:test1Path error:nil];
attributes打印结果:
{
NSFileCreationDate = "2016-04-21 10:10:28 +0000";
NSFileExtensionHidden = 0;
NSFileGroupOwnerAccountID = 20;
NSFileGroupOwnerAccountName = staff;
NSFileModificationDate = "2016-04-21 10:10:28 +0000";
NSFileOwnerAccountID = 501;
NSFilePosixPermissions = 420;
NSFileReferenceCount = 1;
NSFileSize = 26514;
NSFileSystemFileNumber = 6055428;
NSFileSystemNumber = 16777220;
NSFileType = NSFileTypeRegular;
}
attributes属性:
NSFileSize(不可更改)
文件或者文件夹的大小,注意单位是byteNSFileAppendOnly
这个键的值需要设置为一个表示布尔值的NSNumber对象,表示创建的目录是否是只读的。NSFileCreationDate(可更改时间)
这个键的值需要设置为一个NSDate对象,表示目录的创建时间。NSFileOwnerAccountName
这个键的值需要设置为一个NSString对象,表示这个目录的所有者的名字。NSFileGroupOwnerAccountName
这个键的值需要设置为一个NSString对象,表示这个目录的用户组的名字。NSFileGroupOwnerAccountID
这个键的值需要设置为一个表示unsigned int的NSNumber对象,表示目录的组ID。NSFileModificationDate(可更改时间)
这个键的值需要设置一个NSDate对象,表示目录的修改时间。NSFileOwnerAccountID
这个键的值需要设置为一个表示unsigned int的NSNumber对象,表示目录的所有者ID。NSFilePosixPermissions
这个键的值需要设置为一个表示short int的NSNumber对象,表示目录的访问权限。NSFileReferenceCount
这个键的值需要设置为一个表示unsigned long的NSNumber对象,表示目录的引用计数,即这个目录的硬链接数。
修改attribute属性:
- changeAttr:修改的属性的字典
- path:修改的文件的路径
- error:错误报告
注意:attributes里有些属性是不能够修改的,若此时的changeAttr有不能够修改的属性,那changeAttr里能够修改的属性不能够修改成功但是此时API返回的BOOL为YES(见demo3)
[self.fileManager setAttributes:changeAttr ofItemAtPath:test1Path error:&error];
八、写入文件
这是NSData的方法,将data写入文件,如果这个文件存在,则将里面的内容覆盖;如果这个文件不存在,则会创建该文件,然后再将data数据写入
如果文件存在,此时新的二进制数据覆盖文件,修改的时间就会变成当前的时间,创建的时间不变,这和createFileAtPath不一样,createFileAtPath是创建文件,writeToFile是写入文件
- path:写入的文件的路径
- atomically:原子性
注意:
这里将二进制文件写入到文件里面,会清空之前文件里的内容,然后再将二进制文件写入
在将字符串进行data转换的时候,如果是中文字符,此时使用的是NSASCIIStringEncoding
编码,那不会写入到文件,因为这个时候生成的contentData为nil,这个时候可以用NSUnicodeStringEncoding
或者NSUTF8StringEncoding
编码
如果test1Path前面的路径(即/test1Path之前的路径)存在,只是文件不存在,则会生成一个文件,然后将NSData写入,如果 test1Path 所在的路径的中间的路径不存在,则不会写入文件
// 这里可以修改一下 content(纯字符) 和 Encoding 的值,当content为纯字符,Encoding为NSASCIIStringEncoding时没有错误
// 当content为中文,Encoding为NSASCIIStringEncoding写入不进去
NSString *content = @"我是卖报的小当家..啦啦啦啦";
NSData *contentData = [content dataUsingEncoding:NSUnicodeStringEncoding];
if ([contentData writeToFile:test1Path atomically:NO]) {
NSLog(@">>write ok.");
}
九、其他API
- 移动文件
如果folder2不存在,则会创建folder2,将内容拷贝过去,然后删除folder1文件;如果folder2存在,则会报错,同样folder2的中间路径也必须存在,否则会报错
[self.fileManager moveItemAtPath:folder1 toPath:folder2 error:&error];
- 复制文件
folder1文件必须存在,folder2路径所在的中间路径也必须存在,创建folder2,将内容拷贝过去,同时保留folder1文件
[self.fileManager copyItemAtPath:folder1 toPath:folder2 error:&error];
- 取得文件里的内容
NSData *someData = [self.fileManager contentsAtPath:test1Path];
十、代码
demo1 & demo3
-(void)demo1
{
//demo1
/*!
* ~/App Name
*/
NSString *document = NSHomeDirectory();
/*!
* <__NSArrayI 0x7fd3c3e9f920>(
* ~/App Name/Documents
* )
*/
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.document = array.firstObject;
//stringByAppendingPathComponent 函数自动在前一个path的后面加上 "/" 如果后面的一个path的文件名里有 "/" 则会将 "/" 去除
NSString *filePath = [self.document stringByAppendingPathComponent:@"hhhh"];
[self.fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
int i = 1;
NSString *test1Path = [filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"test%d", i]];
i = 2;
NSString *test2Path = [filePath stringByAppendingPathComponent:[NSString stringWithFormat:@"test%d", i]];
i = 3;
NSString *test3Path = [[filePath stringByAppendingPathComponent:@"test3Folder"] stringByAppendingPathComponent:[NSString stringWithFormat:@"test%d", i]];
UIImage *image = [UIImage imageNamed:@"1"];
NSData *data = UIImagePNGRepresentation(image);
BOOL brr = [self.fileManager createFileAtPath:test1Path contents:data attributes:nil];
//这里将二进制文件写入到文件里面,会清空之前文件里的内容,然后再将二进制文件写入
//在将字符串进行data转换的时候,如果是中文字符,此时使用的是NSASCIIStringEncoding编码,那不会写入到文件,因为这个时候生成的contentData为nil,这个时候可以用NSUnicodeStringEncoding 或者 NSUTF8StringEncoding 编码
//如果 test1Path 前面的路径(即/test1Path之前的路径)存在,只是文件不存在,则会生成一个文件,然后将NSData写入,如果 test1Path 所在的路径的中间的路径不存在,则不会写入文件
NSString *content = @"我是卖报的小当家..啦啦啦啦";
NSData *contentData = [content dataUsingEncoding:NSUnicodeStringEncoding];
brr = [self.fileManager createFileAtPath:test1Path contents:contentData attributes:nil];
//此时 test3Path 的中间路径不存在,则不会写入二进制文件
if ([contentData writeToFile:test3Path atomically:NO]) {
NSLog(@">>write ok.");
}
//demo3
NSError *error;
//方法一:修改属性无效,此时修改时间属性没有用,因为attributes里面有些属性是不能修改的
NSDictionary *attr = [self.fileManager attributesOfItemAtPath:test1Path error:&error];
NSDate *date = [attr objectForKey:NSFileCreationDate];
NSMutableDictionary *changeAttr = [NSMutableDictionary dictionaryWithDictionary:attr];
[changeAttr setObject:[NSDate dateWithTimeIntervalSinceNow:600] forKey:NSFileCreationDate];
BOOL rss = [self.fileManager setAttributes:changeAttr ofItemAtPath:test1Path error:&error];
attr = [self.fileManager attributesOfItemAtPath:test1Path error:&error];
//方法二:修改属性有效,此时能够修改时间的属性,打印attr看到时间修改了
[changeAttr removeAllObjects];
[changeAttr setObject:[NSDate dateWithTimeIntervalSinceNow:600] forKey:NSFileCreationDate];
[self.fileManager setAttributes:changeAttr ofItemAtPath:test1Path error:&error];
attr = [self.fileManager attributesOfItemAtPath:test1Path error:&error];
}
demo2
//withIntermediateDirectories为YES会创建中间的目录文件夹,为NO则不会创建目录文件夹
NSString *filePath1 = [[self.document stringByAppendingPathComponent:@"aaaa"] stringByAppendingPathComponent:@"bbbb"];
NSError *fileError1;
[self.fileManager createDirectoryAtPath:filePath1 withIntermediateDirectories:YES attributes:nil error:&fileError1];
NSString *filePath2 = [[self.document stringByAppendingPathComponent:@"cccc"] stringByAppendingPathComponent:@"dddd"];
NSError *fileError2;
[self.fileManager createDirectoryAtPath:filePath2 withIntermediateDirectories:NO attributes:nil error:&fileError2];