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];