移動開發(IOS) – Objective-C-07-文件管理

移動開發(IOS) – Objective-C-07-文件管理

By docoder in 博客學習 on 2014/05/28

ios-objective-c-7

1.沙盒

1.1.iOS 中每個 App 應用程序都有一個單獨封閉的文件夾,這個文件夾稱爲沙盒 ( sandbox )

1.2.沙盒目錄用來存放 App 的本地文件,例如:音頻、視頻、圖片文件 …

1.3.當前 App 應用程序沒權限訪問其他 App 的沙盒。(更安全)

1.4.應用程序包:(Bundle)包含了所有的資源文件和可執行文件。

1.5.沙盒目錄中有如下子目錄:

1.5.1.Documents 存放長期使用的文件。保存應用運行時生成的需要持久化的數據,iTunes同步設備時會備份該目錄。

1.5.2.Library 系統存放文件。Library/Caches, 保存應用運行時生成的需要持久化的數據,iTunes同步設備時不會備份該目錄。一般存儲體積較大、不需要備份的非重要數據。Library/Preference:保存應用的所有偏好設置,iOS的設置應用會在該目錄中查找應用的設置信息。iTunes同步設備時會備份該目錄。

1.5.3.tmp 臨時文件,App 重啓時,該目錄下的文件清空。保存應用運行時所需的臨時數據,使用完畢後再將相應的文件從該目錄刪除。應用沒有運行時,系統也有可能會清除該目錄下的文件。iTunes同步設備時不會備份該目錄。

2.NSString 處理文件路徑

2.1.OC裏的文件路徑通過NSString來描述。

2.2.獲取沙盒路徑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//沙盒的主⺫錄
NSString *homePath = NSHomeDirectory();
 
/***獲取Documents⺫錄***/
//1.
// NSUserDomainMask 代表從用戶文件夾下找
// YES 代表展開路徑中的波浪字符“~”
NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// 只有一個匹配目錄,所以這個集合裏面只有一個元素
NSString *doc = documents[0];
//2.
//使用字符串拼接的方式獲取
//不建議採用字符串拼接的方式獲取目錄,因爲新版本的操作系統可能會修改默認目錄名稱
NSString *documents = [homePath stringByAppendingPathComponent:@"Documents"];
 
/***獲取Cache目錄***/
NSArray *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cache = caches[0];
 
/***獲取Library⺫錄***/
NSString *library = [homePath stringByAppendingPathComponent:@"Library"];
 
/***Preferences目錄***/
//通過NSUserDefaults類存取該目錄下的設置信息
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"docoder" forKey:@"userName"];
[defaults setFloat:18.0f forKey:@"fontSize"];
[defaults setBool:YES forKey:@"autoLogin"];
// 讀取系統偏好
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *userName = [defaults objectForKey:@"userName"];
float fontSize = [defaults floatForKey:@"fontSize"];
BOOL autoLogin = [defaults floatForKey:@"autoLogin"];
//注意:UserDefaults設置數據時,不是立即寫入,而是根據時間戳定時地把緩存中的數據寫入本地磁盤。所以調用了set方法之後數據有可能還沒有寫入磁盤,應用程序就終止了。
//出現以上問題,可以通過調用synchornize方法強制寫入:
[defaults synchronize];
 
/***獲取tmp⺫錄***/
NSString *tmpDir = NSTemporaryDirectory();

2.3.NSString可以對路徑做一些處理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//演⽰路徑
NSString *path = @"/Users/username/file.txt";
//1.獲取路徑的組成部分 結果: (“/”,”Users”, “username”, “file.txt”)
NSArray *components = [path pathComponents];
//2.路徑的最後一個組成部分 結果: file.txt
NSString *lastName = [path lastPathComponent];
//3.追加⽂件或⺫錄 結果: /Users/username/file.txt/app.txt
NSString *filePath = [path stringByAppendingPathComponent:@"app.txt"];
//4.刪除最後部分的組成部分 結果: /Users/username
NSString *filePath = [path stringByDeletingLastPathComponent];
//5.取路徑最後部分的擴展名 結果: txt
NSString *extName = [path pathExtension];
//6.追加擴展名 結果: /Users/username/file.txt.jpg
NSString *filePath = [path stringByAppendingPathExtension:@"jpg"];

3.NSFileManager

3.1.NSFileManager 主要對文件進行管理, 具有:創建文件,複製文件,刪除文件,剪切文件的功能。

3.2.NSFileManager 爲單例,不能用 alloc 創建:

1
2
//創建 NSFileManager 對象
NSFileManager *fileManager = [NSFileManager defaultManager];

3.3.常用方法:

1
2
3
4
5
6
7
8
9
10
11
12
//創建一個⽂件並寫入數據
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;
//從⼀個文件中讀取數據
- (NSData *)contentsAtPath:(NSString *)path;
//srcPath路徑上的⽂件移動到 dstPath 路徑上, 注意這裏的路徑是⽂件路徑⽽不是目錄
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
//srcPath路徑上的文件複製到 dstPath 路徑上
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error;
//文件是否存在
- (BOOL)fileExistsAtPath:(NSString *)path;
// 移除⽂件
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;

3.4.創建文件:

1
2
3
4
5
6
7
8
9
//創建 NSFileManager 對象
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"file.txt"];
NSString *text = @"docoder";
//將字符串轉成NSData類型
NSData *data = 1;
//寫⼊文件
BOOL success = [fileManager createFileAtPath:path contents:data attributes:nil];

3.5.讀取文件

1
2
3
4
5
6
//創建 NSFileManager 對象
NSFileManager *fileManager = [NSFileManager defaultManager];
//根據路徑讀取文件
NSData *fileData = [fileManager contentsAtPath:filePath];
//將NSData轉NSString
NSString *content = [[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];

3.6.剪切、複製

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
NSString *homePath = NSHomeDirectory();
//源⽂件路徑
NSString *srcPath = [homePath stringByAppendingPathComponent:@"file.txt"];
//目標路徑
NSString *toPath = [homePath stringByAppendingPathComponent:@"Documents/file.txt"];
 
NSError *error;
//剪切(移動)文件
//將srcPath路徑的文件剪切(移動)到toPath路徑
BOOL isSuccess = [fm moveItemAtPath:srcPath toPath:toPath error:&error];
if(!isSuccess){
    NSLog(@"失敗:%@",error);
}
//複製文件
//將srcPath路徑的⽂件複製到toPath路徑
BOOL success = [fm copyItemAtPath:srcPath toPath:toPath error:nil];

3.7.刪除文件

1
2
3
4
5
6
7
8
9
//判斷⽂件是否存在
BOOL isExist = [fm fileExistsAtPath: path];
if (isExist) {
    //刪除⽂件
    BOOL success = [fm removeItemAtPath:path error:nil];
    if (success) {
        NSLog(@"remove success");
    }
}

3.8.獲取文件大小

3.8.1.通過讀取文件屬性獲得:

1
2
3
4
5
NSFileManager *fileManager = [NSFileManager defaultManager];
//獲得文件的屬性字典
NSDictionary *attrDic = [fileManager attributesOfItemAtPath:path error:nil];
//獲取⽂件⼤小
NSNumber *fileSize = [attrDic objectForKey:NSFileSize];

3.8.2.計算獲得 (此方法如果讀取大文件會很佔有內存,不建議使用):

1
2
3
NSFileManager *fileManager = [NSFileManager defaultManager];
NSData *data = [fileManager contentsAtPath:path];
NSInteger len=data.length;

4.writeToFile 寫文件

4.1.數組、字典、字符串、NSData 都是容納數據的,他們都有一個 writeToFile 方法, 將數據寫入文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSString *string = @"docoder";
NSError *error;
 
//atomically:YES,表示寫成功後(會寫入到臨時文件中)再覆蓋文件,若寫入失敗,則不會覆蓋文件,這樣更安全。
BOOL isSuccess = [string writeToFile:path atomically:YES encoding: NSUTF8StringEncoding error: &error]
 
if(!isSuccess){
    NSLog(@"寫入失敗:%@",error);
}else{
    NSLog(@"寫入成功");
}
 
NSString *backString = [NSString stringWithContentsOfFile:path encoding: NSUTF8StringEncoding error: nil]
NSLog(@"取回字符串:%@",backString);

4.2.數組寫入文件:

1
2
3
4
5
6
7
8
9
10
NSString *s1 = @"zhangsan";
NSString *s2 = @"lisi";
NSArray *array = [NSArray arrayWithObjects:s1,s2, nil];
//將數組中的數據寫⼊文件
[array writeToFile:path atomically:YES];
 
//取回寫入的數組(alloc)
NSArray *backArray=[[NSArray alloc] initWithContentsOfFile:path];
//取回寫入的數組(類方法)
NSArray *backArray = [NSArray arrayWithContentsOfFile:path];

4.3.數組只能將如下數據類型寫入文件,如果包含其他對象,將寫入失敗。

NSNumber NSString NSData NSDate NSArray NSDictionary

4.4.數組、字典寫入的文件叫屬性列表 (plist) 文件 (一種XML格式的文件),可以用xcode打開編輯。

4.5.如果所指定保存文件的路徑不存在,寫入文件方法不會報錯,文件也不會被保存。

4.6.其他格式數據的保存:

4.6.1.NSString , 保存時需要自定字符串編碼。

4.6.2.UIImage , 注意UIImage無法寫入文件,需要使用NSData數據類型進行中轉,NSData可以將任何類型的文件,以二進制格式存儲。

1
2
// 生成圖像數據
NSData *data = UIImagePNGRepresentation(image);

5.NSFileHandle

5.1.NSFileManager 主要對文件進行 (刪除、修改、移動、複製)。NSFileHandle 主要是對文件的內容進行讀取和寫入操作。

5.2.NSFileHandle 不能創建文件,只能對現有文件進行讀寫,並且可以通過文件偏移量來定位讀寫。

5.3.常用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//創建NSFileHandle,並且打開文件準備讀取
+ (id)fileHandleForReadingAtPath:(NSString *)path;
//創建NSFileHandle,並且打開⽂件準備寫入
+ (id)fileHandleForWritingAtPath:(NSString *)path;
//創建NSFileHandle,並且打開文件準備寫入或讀取
+ (id)fileHandleForUpdatingAtPath:(NSString *)path;
//讀取文件全部數據
- (NSData *)availableData;
//寫⼊數據
- (void)writeData:(NSData *)data;
 
// 獲取當前⽂件的偏移量
- (unsigned long long)offsetInFile;
// 跳到指定⽂件的偏移量
- (void)seekToFileOffset:(unsigned long long)offset;
// 使偏移量跳到文件末尾
- (unsigned long long)seekToEndOfFile;
// 從當前偏移量讀取到文件末尾
- (NSData *)readDataToEndOfFile;
// 從當前偏移量開始讀取指定的長度數據
- (NSData *)readDataOfLength:(NSUInteger)length;

5.4.向文件追加數據:

1
2
3
4
5
6
7
8
9
10
11
NSString *sourcePath = [NSHomeDirectory() stringByAppendingPathComponent:@"file.txt"];
//創建可讀寫的 NSFileHandle 對象
NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:sourcePath];
//將偏移量跳到文件末尾
[fileHandle seekToEndOfFile];
NSString *str = @"追加的數據";
NSData *stringData = [str dataUsingEncoding:NSUTF8StringEncoding];
//寫⼊數據
[fileHandle writeData:stringData];
//關閉⽂件
[fileHandle closeFile];

5.5.定位偏移量讀取:

1
2
3
4
5
6
7
8
9
10
11
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *fileAttr = [fileManager attributesOfItemAtPath:filePath error:nil];
NSNumber *filesize = [fileAttr objectForKey:NSFileSize];
long length = [filesize longValue];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
// 將偏移量定位到⽂件⻓度的一半
[fileHandle seekToFileOffset:length/2];
// 從當前偏移量讀到⽂件最後
NSData *data = [fileHandle readDataToEndOfFile];
// 關閉⽂件
[fileHandle closeFile];

5.6.使用NSFileHandle實現複製文件功能:

此方法將全部數據一次讀,一次寫,若文件很大,會很佔內存,可以將其改爲分批讀寫。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *homePath = NSHomeDirectory();
//源⽂件路徑
NSString *sourcePath = [homePath stringByAppendingPathComponent:@"srcfile.txt"];
//輸出⽂件路徑
NSString *outPath = [homePath stringByAppendingPathComponent:@"outfile.txt"];
//創建輸出文件
BOOL success = [fileManager createFileAtPath:outPath contents:nil attributes:nil];
if (!success) {
    NSLog(@"創建⽂件失敗");
}
//創建NSFileHandle,用於讀取源路徑文件
NSFileHandle *infile = [NSFileHandle fileHandleForReadingAtPath:sourcePath];
if (infile == nil) {
    NSLog(@"打開失敗:路徑:%@",sourcePath);
}
//創建NSFileHandle,⽤於將數據寫入該文件
NSFileHandle *outfile = [NSFileHandle fileHandleForWritingAtPath:outPath];
if (outfile == nil) {
    NSLog(@"打開失敗:路徑:%@",outPath);
}
//從當前偏移量讀取文件剩下的所有數據
NSData *buffer = [infile availableData];
//將數據寫⼊輸出文件
[outfile writeData:buffer];
//關閉寫入、輸入⽂件
[infile closeFile];
[outfile closeFile];

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章