OC學習15——檔案I/O體系
阿新 • • 發佈:2022-04-29
OC提供了豐富的I/O相關API,如果只是管理檔案和目錄,程式可以使用NSFileManager進行管理,包括建立、刪除、移動和複製檔案等;如果程式需要讀取檔案內容,則可通過NSFileHandle進行處理;如果需要讀取網路資源,則可通過NSURL進行處理;如果程式只是讀取專案內部資源,則可藉助MSBundle進行處理。
1、Foundation提供了NSData和NSMutableData,他們代表OC的資料緩衝區。NSData的作用有兩個:將資料讀入NSData;輸出NSData的資料。
1 #import <Foundation/Foundation.h> 2 3 int main(int argc , char * argv[]) 4 { 5 @autoreleasepool{ 6 // 使用NSData讀取指定URL對應的資料 7 NSData* data = [NSData dataWithContentsOfURL: 8 [NSURL URLWithString:@"http://www.crazyit.org/ethos.php"]]; 9 NSLog(@"%ld" , [data length]); 10 // 定義一個長度為100的陣列 11 char buffer[100]; 12 // 將NSData指定範圍的資料讀入陣列 13 [data getBytes:buffer range: NSMakeRange(103, 100)]; 14 // 輸出陣列的內容 15 NSLog(@"%s" , buffer); 16 // 直接將NSData的資料用UTF-8的格式轉換字串 17 NSString* content = [[NSString alloc] initWithData:data 18 encoding:NSUTF8StringEncoding]; 19 NSLog(@"----------輸出網頁內容---------"); 20 NSLog(@"%@" , content); 21 } 22 }
2、使用NSFileManager管理檔案和目錄
- 相對路徑:不以斜線開頭的路徑都是相對路徑。相對路徑都是以當前路徑下為基礎路徑,隨著當前路徑的不同,同一個相對路徑實際代表的檔案可能發生變化,在終端視窗輸入pwd可以看到當前路徑。
- 絕對路徑:以斜線(代表根目錄)開頭的路徑都是絕對路徑。絕對路徑是唯一的,它代表的檔案或目錄總是固定的。
此外,Mac OS X中還包括幾個特殊的路徑:
- ~:代表當前使用者的home目錄,eg:當前使用者是"keli",則~代表的/Users/keli
- .:代表當前目錄
- ..:代表當前目錄的上一級目錄
NSFileManager可以訪問檔案的屬性和內容,具體相關方法查詢 NSFileManager文件
1 #import <Foundation/Foundation.h> 2 3 int main(int argc , char * argv[]) 4 { 5 @autoreleasepool{ 6 NSFileManager* fm = [NSFileManager defaultManager]; 7 // 將會輸出代表真的1 8 NSLog(@"NSFileManagerTest.m是否存在:%d", 9 [fm fileExistsAtPath:@"NSFileManagerTest.m"]); 10 BOOL isDir; 11 NSLog(@"NSFileManagerTest.m是否存在:%d", 12 [fm fileExistsAtPath:@"NSFileManagerTest.m" 13 isDirectory: &isDir]); 14 // 將會輸出代表假的0 15 NSLog(@"NSFileManagerTest.m是否為目錄:%d", isDir); 16 // 將會輸出代表真的1 17 NSLog(@"NSFileManagerTest.m是否為可讀檔案:%d", 18 [fm isReadableFileAtPath:@"NSFileManagerTest.m"]); 19 // 將會輸出代表真的1 20 NSLog(@"NSFileManagerTest.m是否為可寫檔案:%d", 21 [fm isWritableFileAtPath:@"NSFileManagerTest.m"]); 22 // 將會輸出代表假的0 23 NSLog(@"NSFileManagerTest.m是否為可執行檔案:%d", 24 [fm isExecutableFileAtPath:@"NSFileManagerTest.m"]); 25 // 將會輸出代表真的1 26 NSLog(@"NSFileManagerTest.m是否為可刪除檔案:%d", 27 [fm isDeletableFileAtPath:@"NSFileManagerTest.m"]); 28 // 獲取NSFileManagerTest.m檔案所在的路徑元件 29 NSArray* array = [fm componentsToDisplayForPath: 30 @"NSFileManagerTest.m"]; 31 NSLog(@"--NSFileManagerTest.m所在路徑的完整路徑元件為:--"); 32 for(NSObject* ele in array) 33 { 34 NSLog(@"%@ , " , ele); 35 } 36 // 獲取檔案的相關屬性 37 NSDictionary* attr = [fm attributesOfItemAtPath:@"NSFileManagerTest.m" 38 error:nil]; 39 // 獲取檔案屬性的詳情 40 NSLog(@"NSFileManagerTest.m的建立時間為:%@", 41 [attr fileCreationDate]); 42 NSLog(@"NSFileManagerTest.m的屬主賬戶為:%@", 43 [attr fileOwnerAccountName]); 44 NSLog(@"NSFileManagerTest.m的檔案大小為:%lld", 45 [attr fileSize]); 46 // 直接獲取檔案內容 47 NSData* data = [fm contentsAtPath:@"NSFileManagerTest.m"]; 48 // 直接將NSData的資料用UTF-8的格式轉換字串 49 NSString* content = [[NSString alloc] initWithData:data 50 encoding:NSUTF8StringEncoding]; 51 NSLog(@"----------輸出檔案內容---------"); 52 NSLog(@"%@" , content); 53 } 54 }
NSFileManager對檔案或目錄進行建立、刪除、移動和複製:
1 #import <Foundation/Foundation.h>
2
3 int main(int argc , char * argv[])
4 {
5 @autoreleasepool{
6 NSFileManager* fm = [NSFileManager defaultManager];
7 // 建立目錄
8 [fm createDirectoryAtPath:@"xyz/abc"
9 // 該引數指定如果父目錄不存在,建立父目錄
10 withIntermediateDirectories:YES
11 attributes:nil
12 error:nil];
13 NSString* content = @"《瘋狂iOS講義》是我正在學習的圖書!";
14 // 建立一份檔案
15 [fm createFileAtPath:@"myInfo.txt"
16 contents:[content dataUsingEncoding:NSUTF8StringEncoding]
17 attributes:nil];
18 // 複製一份新檔案
19 [fm copyItemAtPath:@"myInfo.txt"
20 toPath:@"copyInfo.txt"
21 error:nil];
22 }
23 }
檢視目錄包含的內容:
1 #import <Foundation/Foundation.h>
2
3 int main(int argc , char * argv[])
4 {
5 @autoreleasepool{
6 NSFileManager* fm = [NSFileManager defaultManager];
7 // 獲取指定目錄下所有檔案和資料夾
8 NSArray * array = [fm contentsOfDirectoryAtPath:@"."
9 error:nil];
10 for(NSString* item in array)
11 {
12 NSLog(@"%@" , item);
13 }
14 // 獲取指定目錄下所有檔案和資料夾對應的列舉器
15 NSDirectoryEnumerator* dirEnum =
16 [fm enumeratorAtPath:@"."];
17 NSString *file;
18 // 列舉dirEnum中包含的每個檔案
19 while ((file = [dirEnum nextObject]))
20 {
21 // 如果該檔案的檔名以.m結尾
22 if ([[file pathExtension] isEqualToString: @"m"]) {
23 // 直接獲取檔案內容
24 NSData* data = [fm contentsAtPath:file];
25 // 直接將NSData的資料用UTF-8的格式轉換字串
26 NSString* content = [[NSString alloc] initWithData:data
27 encoding:NSUTF8StringEncoding];
28 NSLog(@"----------輸出檔案內容---------");
29 NSLog(@"%@" , content);
30 }
31 }
32 // 獲取當前目錄下的所有子目錄
33 // NSArray* subArr = [fm subpathsOfDirectoryAtPath:@"."
34 // error:nil];
35 NSArray* subArr = [fm subpathsAtPath:@"."];
36 for(NSString* item in subArr)
37 {
38 NSLog(@"%@" , item);
39 }
40 }
41 }
4、使用NSPathUtilities.h管理路徑,NSPathUtilities.h包含了對NSString類的擴充套件,從而為NSString類新增了一些專門用於操作路徑的方法,這些方法的主要作用就是更方便第操作路徑
1 #import <Foundation/Foundation.h>
2
3 int main(int argc , char * argv[])
4 {
5 @autoreleasepool{
6 NSLog(@"當前使用者名稱為:%@" , NSUserName());
7 NSLog(@"當前使用者的完整使用者名稱為:%@" , NSFullUserName());
8 NSLog(@"當前使用者的home目錄為:%@" , NSHomeDirectory());
9 NSLog(@"root使用者的home目錄為:%@" ,
10 NSHomeDirectoryForUser(@"root"));
11 NSLog(@"系統臨時目錄為:%@" ,
12 NSTemporaryDirectory());
13 NSString* path = @"~root";
14 // 將~root解析成root使用者的home目錄
15 NSLog(@"解析~root的結果:%@" ,
16 [path stringByExpandingTildeInPath]);
17 NSString* path2 = @"/Users/yeeku/publish";
18 // 將會輸出~/publish
19 NSLog(@"替換成~的形式:%@" ,
20 [path2 stringByAbbreviatingWithTildeInPath]);
21 NSArray* array = [path2 pathComponents];
22 // 遍歷該路徑中包含的各路徑元件
23 for(NSString* item in array)
24 {
25 NSLog(@"%@" , item);
26 }
27 // 在path2路徑後追加一個路徑
28 NSString* path3 = [path2 stringByAppendingPathComponent:@"abc.m"];
29 NSLog(@"path3為:%@" , path3);
30 // 獲取路徑的最後部分
31 NSString* last = [path3 lastPathComponent];
32 NSLog(@"path3的最後一個路徑元件為:%@" , last);
33 // 獲取路徑的最後部分的副檔名
34 NSLog(@"path3的最後一個路徑的副檔名為:%@" ,
35 [path3 pathExtension]);
36 }
37 }
5、使用NSProcessInfo獲取程序資訊,包括獲取執行該程式的引數、程序識別符號等,還可以用於獲取該程序所在系統的主機名、作業系統名、作業系統版本等資訊。
1 #import <Foundation/Foundation.h>
2
3 int main(int argc , char * argv[])
4 {
5 @autoreleasepool{
6 // 獲取當前程序對應的ProcessInfo物件
7 NSProcessInfo* proInfo = [NSProcessInfo processInfo];
8 // 獲取執行該程式所指定的引數
9 NSArray* arr = [proInfo arguments];
10 NSLog(@"執行程式的引數為:%@" , arr);
11 NSLog(@"程序識別符號為:%d" ,
12 [proInfo processIdentifier]);
13 NSLog(@"程序的程序名為:%@" ,
14 [proInfo processName]);
15 NSLog(@"程序所在系統的主機名為:%@"
16 , [proInfo hostName]);
17 NSLog(@"程序所在系統的作業系統為:%ld"
18 , [proInfo operatingSystem]);
19 NSLog(@"程序所在系統的作業系統名為:%@"
20 , [proInfo operatingSystemName]);
21 NSLog(@"程序所在系統的作業系統版本字串為:%@"
22 , [proInfo operatingSystemVersionString]);
23 NSLog(@"程序所在系統的實體記憶體為:%lld"
24 , [proInfo physicalMemory]);
25 NSLog(@"程序所在系統的處理器數量為:%ld"
26 , [proInfo processorCount]);
27 NSLog(@"程序所在系統的啟用的處理器數量為:%ld"
28 , [proInfo activeProcessorCount]);
29 NSLog(@"程序所在系統的執行時間為:%f"
30 , [proInfo systemUptime]);
31 }
32 }
6、可以通過NSFileHandle讀取檔案內容,使用NSFileHandle的基本步驟如下:
- 建立一個NSFileHandle,該NSFileHandle將會開啟指定檔案
- 對開啟的檔案進行IO操作
- 關閉檔案
1 #import <Foundation/Foundation.h>
2
3 int main(int argc , char * argv[])
4 {
5 @autoreleasepool{
6 // 開啟一份檔案準備讀取
7 NSFileHandle* fh = [NSFileHandle
8 fileHandleForReadingAtPath:@"NSFileHandleTest.m"];
9 NSData* data;
10 // 讀取NSFileHandle中的256個位元組
11 while( [(data = [fh readDataOfLength:512]) length] > 0 )
12 {
13 NSLog(@"%ld" , [data length]);
14 // 直接將NSData的資料用UTF-8的格式轉換字串
15 NSString* content = [[NSString alloc] initWithData:data
16 encoding:NSUTF8StringEncoding];
17 NSLog(@"----------輸出讀取的512個位元組的內容---------");
18 NSLog(@"%@" , content);
19 }
20
21 // 關閉檔案
22 [fh closeFile];
23 // 開啟一份檔案準備寫入
24 NSFileHandle* fh2 = [NSFileHandle
25 fileHandleForWritingAtPath:@"abc.txt"];
26 if(!fh2)
27 {
28 // 建立一個NSFileManager物件
29 NSFileManager* fm = [NSFileManager defaultManager];
30 // 建立一份空的檔案
31 [fm createFileAtPath:@"abc.txt"
32 contents:nil
33 attributes:nil];
34 fh2 = [NSFileHandle
35 fileHandleForWritingAtPath:@"abc.txt"];
36 }
37 NSString* myBook = @"瘋狂iOS講義";
38 // 將指定內容寫入底層檔案
39 [fh2 writeData:[myBook
40 dataUsingEncoding:NSUTF8StringEncoding]];
41 // 關閉檔案
42 [fh2 closeFile];
43 }
44 }