Foundation 架構請允許你利用檔案系統對檔案或目錄執行基本操作。這些基本操作是由NSFileManager類提供的,
這個類的方法具有如下功能:
- 建立 一個新檔案
- 從現有檔案中讀取資料
- 將資料寫入檔案中
- 重新命名檔案
- 刪除檔案
- 測試檔案是否存在
- 確定檔案的大小及其他屬性
- 複製檔案
- 測試兩個檔案的內容是否相同
上述多資料操作也可以直接對目錄進行。例如,可以建立目錄,讀取其中的內容,或者刪除目錄。
管理檔案和目錄
每個檔案方法都是對NSFileManager對象的調用,而NSFileManager對象 是通過向類發送一條defaultManager訊息建立的,
如下所示:
NSFileManager *fm
...
fm = [NSFileManager defaultManager];
例如,要從目前的目錄刪除名為todolist的檔案,首先要建立一個NSFileManager對象(如前面所示),然後調用removeFileAtPath方法,
代碼如下:
[fm removeFileAtPath: @"todolist" handler:nil];
可以測試返回結果,以確保檔案刪除:
if([fm removeFileAtPath:@"todolist" handler:nil] == NO)
{
NSLog(@"Couldn't remove file todolist");
return 1;
}
下面是一個基本檔案操作的例子:
//Basic ifle operations<br />//Assumes the existence of a file called "testfile"<br />//in ther current working directory<br />#import <Foundation/NSObject.h><br />#import <Foundation/NSString.h><br />#import <Foundation/NSFileManager.h><br />#import <Foundation/NSAutoreleasePool.h><br />#import <Foundation/NSDictionary.h></p><p>int main(int argc, const char *argv[])<br />{<br /> NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];<br /> NSString *fName = @"testfile.txt";<br /> NSFileManager *fm;<br /> NSDictionary *attr;</p><p> //Need to create an instance of the file manager<br /> fm = [NSFileManager defaultManager];</p><p> //Let's make sure our test file exists first<br /> if([fm fileExistsAtPath: fName] == NO)<br /> {<br /> NSLog(@"File doesn't exist'");<br /> return 1;<br /> }</p><p> //Now let's make a copy</p><p> if([fm copyPath: fName toPath: @"newfile.txt" handler:nil] == NO)<br /> {<br /> NSLog(@"File copy failed");<br /> return 2;<br /> }</p><p> //Let's test to see if the two files are identical<br /> if([fm contentsEqualAtPath: fName andPath: @"newfile.txt"] == NO)<br /> {<br /> NSLog(@"Files are not equal!");<br /> return 3;<br /> }</p><p> //Now let's rename the copy</p><p> if([fm movePath: @"newfile.txt" toPath: @"newfile2.txt" handler:nil] == NO)<br /> {<br /> NSLog(@"File rename failed!");<br /> return 4;<br /> }</p><p> //Get the size of newfile2</p><p> if((attr = [fm fileAttributesAtPath: @"newfile2.txt" traverseLink:NO]) == nil)<br /> {<br /> NSLog(@"Couldn't get file attributes!");<br /> return 5;<br /> }</p><p> NSLog(@"File size is %i bytes",[[attr objectForKey: NSFileSize] intValue]);</p><p> //And finally, let's delete the original file<br /> if([fm removeFileAtPath: fName handler:nil] == NO)<br /> {<br /> NSLog(@"File removal failed!");<br /> return 6;<br /> }</p><p> NSLog(@"All operations were successful!");</p><p> //Display the contents of the newly-created file</p><p> NSLog(@"%@",[NSString stringWithContentsOfFile:@"newfile2.txt" encoding:NSUTF8StringEncoding error:nil]);</p><p> [pool drain];<br /> return 0;<br />}<br />
使用NSData類
使用檔案時,需要頻繁地將資料讀入一個臨時儲存區,它通常稱為緩衝區。當收集資料,以便隨後將這些資料輸出到檔案中時,
通常也使用儲存區。Foundation的NSData類提供了一種簡單的方式,它用來設定緩衝 區、將檔案的內容讀入緩衝區,或將
緩衝區的內容寫到一個檔案。
下面是一個使用NSData 的例子:
#import <Foundation/NSObject.h><br />#import <Foundation/NSString.h><br />#import <Foundation/NSFileManager.h><br />#import <Foundation/NSAutoreleasePool.h><br />#import <Foundation/NSData.h></p><p>//make a copy of file<br />int main(int argc, const char *argv[])<br />{<br /> NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];<br /> NSFileManager *fm;<br /> NSData *fileData;</p><p> fm = [NSFileManager defaultManager];</p><p> //Read the file newfile2<br /> fileData = [fm contentsAtPath: @"newfile2.txt"];</p><p> if(fileData == nil)<br /> {<br /> NSLog(@"File read failed!");<br /> return 1;<br /> }</p><p> //Write the data to newfile3<br /> if([fm createFileAtPath: @"newfile3.txt" contents: fileData attributes:nil] == NO)<br /> {<br /> NSLog(@"Couldn't create the copy!");<br /> return 2;<br /> }</p><p> NSLog(@"File copy was successful!");</p><p> [pool drain];<br /> return 0;<br />}</p><p>
使用目錄
NSFileManager類中,還有很多操作目錄的方法。
下面是一個例子:
#import <Foundation/NSObject.h><br />#import <Foundation/NSString.h><br />#import <Foundation/NSFileManager.h><br />#import <Foundation/NSAutoreleasePool.h></p><p>int main(int argc, const char *argv[])<br />{<br /> NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];<br /> NSFileManager *fm;<br /> NSString *dirName = @"testdir";<br /> NSString *path;</p><p> fm = [NSFileManager defaultManager];</p><p> //Get current directory<br /> path = [fm currentDirectoryPath];<br /> NSLog(@"Current directory path is %@",path);</p><p> //Create a new directory<br /> if([fm createDirectoryAtPath: dirName attributes: nil] == NO)<br /> {<br /> NSLog(@"Couldn't create directory!");<br /> return 1;<br /> }</p><p> //Rename the new directory<br /> if([fm movePath: dirName toPath: @"newdir" handler: nil] == NO)<br /> {<br /> NSLog(@"Directory rename failed!");<br /> return 2;<br /> }</p><p> //Change directory into the new directory<br /> if([fm changeCurrentDirectoryPath: @"newdir"] == NO)<br /> {<br /> NSLog(@"Change directory failed!");<br /> return 3;<br /> }</p><p> //Now get and display current working directory<br /> path = [fm currentDirectoryPath];<br /> NSLog(@"Current directory path is %@ ",path);</p><p> NSLog(@"All operations were successful!");</p><p> [pool drain];<br /> return 0;<br />}</p><p>
枚舉目錄中的內容
有時需要枚舉目錄是的內容,就需要用到enumeratorAtPath:方法或者directoryContentsAtPath: 方法,來完成枚舉過程。
如果使用第一種方法,一次可以枚舉指定目錄中的每個檔案,預設情況下,如果其中一個檔案為目錄,那麼也會遞迴枚舉它的內容。
在這個過程中,通過向枚舉對象發送一條skipDescendants訊息,可以動態地阻止遞迴過程,從而不再枚舉目錄中的內容。
對於directoryContentsAtPath:方法,使用這個方法,可心枚舉指定目錄的內容,並在一個數組中返迴文件列表。
如果這個目錄中的任何檔案本身是個目錄,這個方法並不遞迴枚舉它的內容。
下面一個例子是這兩個方法的使用:
#import <Foundation/NSArray.h><br />#import <Foundation/NSString.h><br />#import <Foundation/NSFileManager.h><br />#import <Foundation/NSAutoreleasePool.h></p><p>//enumeratorAtPath:方法和directoryContentsAtPath:方法<br />//的區別是:前者遍曆子目錄,後者不遍曆子目錄<br />int main(int argc, const char *argv[])<br />{<br /> NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];<br /> NSFileManager *fm;<br /> NSString *path;<br /> NSDirectoryEnumerator *dirEnum;<br /> NSArray *dirArray;</p><p> fm = [NSFileManager defaultManager];</p><p> //Get current directory path<br /> path = [fm currentDirectoryPath];</p><p> //Enumerate the directory</p><p> dirEnum = [fm enumeratorAtPath:path];</p><p> NSLog(@"Contents of %@: ",path);<br /> while((path = [dirEnum nextObject]) != nil)<br /> NSLog(@"%@",path);</p><p> //Another way to enumerate a directory<br /> dirArray = [fm directoryContentsAtPath:[fm currentDirectoryPath]];<br /> NSLog(@"Contents using directoryContentsAtPath:");</p><p> for(int i = 0; i < [dirArray count];i++)<br /> {<br /> NSLog(@"%@",[dirArray objectAtIndex: i]);<br /> }</p><p> [pool drain];<br /> return 0;<br />}</p><p>