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 }