1. 程式人生 > 其它 >OC學習15——檔案I/O體系

OC學習15——檔案I/O體系

  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 }