[绍棠] iOS文件目录和文件操作 及NSFileManager的读写操作

时间:2021-08-04 03:30:22

1.理解部分 

1.1文件

<1>文件管理类NSFileManager

2.对文件进行管理操作

a.遍历查看目录下的文件

【深度遍历】

【浅度遍历】

b.创建文件/目录

c.拷贝文件/目录

d.移动文件/目录

e.删除文件/目录

<2>文件句柄类NSFileHandle

1.对文件进行读写首先需要NSFileHandle打开文件

2.NSFileHandle对文件进行读写都是NSData类型的二进制数据

2.实践部分

2.1 NSFileManager

<1>创建文件管理器单例对象

NSFileManager * fm = [NSFileManager defaultManager];

<2>遍历目录下的内容

//浅度遍历

//仅仅遍历当前文件夹下的第一层子文件夹

/// //contentsOfDirectoryAtPath,指定路径下的第一层子文件夹(文件内容)

- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;

//深度遍历(又称为递归便利)

//遍历指定路径下的所有文件夹和文件

//指定路径下的子文件夹下的所有文件

- (NSArray *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error

<3>创建文件

//创建普通文件

//createFileAtPath,在指定路径下,创建文件

//第二个参数contents,是指在创建文件的同时,附上的文件内容

//第三个参数attributes ,如果写nil, attributes会有系统自动管理

- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;

//创建目录

//就是在指定路径下创建文件夹

//withIntermediateDirectories,是否创建没有路径

- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error ;

<4>拷贝文件/目录

//copyItemAtPath,在指定路径下拷贝项目(文件夹,也能文件)

//srcPath,原路径

//toPath,目标路径

- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error ; 

<5>移动文件/目录

//moveItemAtPath,移动指定路径下的文件或目录,到另外一个指定的路径

//剪切的同时,也能修改目录或文件的名字

- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error ; 

<6>删除文件/目录

//removeItemAtPath 删除指定路径下的文件夹或者文件

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;

<7>获取文件属性

// attributesOfItemAtPath 查看指定目录下的文件或者文件夹的属性

- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error;

<8>判断文件是否存在

- (BOOL)fileExistsAtPath:(NSString *)path; 

2.2 NSFileHandle

NSFileHandle 对文件进行操作,读,写,设置文件指针偏移量的操作

2.2.1方法:

<1>打开文件方法

//以只读方式打开

 + (id)fileHandleForReadingAtPath:(NSString *)path;

//以只写方式打开

+ (id)fileHandleForWritingAtPath:(NSString *)path;

//以读写方式打开

+ (id)fileHandleForUpdatingAtPath:(NSString *)path;

<2>读指定长度的数据

//readDataOfLength 读取指定长度的字符串

//得知,每个汉字在编译器中占三个字节,英文一个字节

- (NSData *)readDataOfLength:(NSUInteger)length;

<3>从当前偏移量读到文件尾

//是将文本中所有的数据一次性读到内存中

- (NSData *)readDataToEndOfFile;

<4>设置文件偏移量

//2.txt中的文字abcefg,如果偏移量为2的话,那么就是从c字符往后读

//偏移量的默认值为0

- (void)seekToFileOffset:(unsigned long long)offset;

<5>将文件偏移量定位到文件尾

//将指针指向文本的结尾

- (unsigned long long)seekToEndOfFile;

<6>写文件

//(NSData *)data,内存数据类型

// NSString *string=@“abc”,[string dataUsingEncoding:NSUTF8StringEncoding]

- (void)writeData:(NSData *)data;

<7>将文件偏移量以后的内容删除,

//(unsigned long long)offset这个参数用于设置文件偏移量

- (void)truncateFileAtOffset:(unsigned long long)offset;

#program  mark   - NSFileManager的读写操作

  1. -(void) write
  2. {
  3. //创建文件管理器
  4. NSFileManager *fileManager = [NSFileManager defaultManager];
  5. //获取路径
  6. //参数NSDocumentDirectory要获取那种路径
  7. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  8. NSString *documentsDirectory = [paths objectAtIndex:0];//去处需要的路径
  9. //更改到待操作的目录下
  10. [fileManager changeCurrentDirectoryPath:[documentsDirectory stringByExpandingTildeInPath]];
  11. //[fileManager removeItemAtPath:@"config" error:nil];//移除本文件管理器下的该项
  12. NSString *path = [documentsDirectory stringByAppendingPathComponent:@"config"];//获取文件路径
  13. //判断文件是否存在
  14. if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {//如果文件不存在则创建
  15. //创建文件fileName文件名称,contents文件的内容,如果开始没有内容可以设置为nil,attributes文件的属性,初始为nil
  16. NSData *d_data=[[NSMutableDictionary alloc] init];
  17. [d_data setValue:@"" forKey:@"userid"];//手机号
  18. [d_data setValue:@"" forKey:@"pwd"];//密码
  19. [d_data setValue:@"0" forKey:@"backup"];//备份类型
  20. [fileManager createFileAtPath:path contents:d_data attributes:nil];
  21. NSString *str = @"a test file name";
  22. BOOL succeed = [str writeToFile: [documentsDirectory stringByAppendingPathComponent:@"test.xml"]
  23. atomically: YES
  24. encoding: NSUTF8StringEncoding
  25. error: nil];
  26. NSLog( @"succeed is %d", succeed ); // yes -> 写成功 no->写失败
  27. [d_data release];
  28. }
  29. }
  30. - (void)read
  31. {
  32. //读取数据
  33. NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath: @"test.xml"];
  34. NSData *data = [file readDataToEndOfFile];//得到xml文件 //读取到NSDate中
  35. NSString* aStr;
  36. aStr = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; //转换为NSString
  37. NSLog( @"aStr is %@", aStr );
  38. [file closeFile];
  39. }
  40. //对于错误信息
  41. NSError *error;
  42. // 创建文件管理器
  43. NSFileManager *fileMgr = [NSFileManagerdefaultManager];
  44. //指向Documents目录
  45. NSString *documentsDirectory= [NSHomeDirectory()stringByAppendingPathComponent:@"Documents"];
  46. //创建一个目录
  47. [[NSFileManager defaultManager] createDirectoryAtPath: [NSString stringWithFormat:@"%@/myFolder", NSHomeDirectory()] attributes:nil];
  48. 创建一个文件现在我们已经有了文件目录,我们就能使用这个路径在沙盒中创建一个新文件并编写一段代码:
  49. // File we want to create in the documents directory
  50. 我们想要创建的文件将会出现在文件目录中
  51. // Result is: /Documents/file1.txt 结果为:/Documents/file1.txt
  52. NSString *filePath= [documentsDirectorystringByAppendingPathComponent:@"file1.txt"];
  53. //需要写入的字符串
  54. NSString *str= @"iPhoneDeveloper Tips\nhttp://iPhoneDevelopTips,com";
  55. //写入文件[str writeToFile:filePath atomically:YESencoding:NSUTF8StringEncoding error:&error];
  56. //显示文件目录的内容
  57. NSLog(@"Documentsdirectory: %@",[fileMgr contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);
  58. NSFileManager *fileManager = [NSFileManager defaultManager];
  59. //在这里获取应用程序Documents文件夹里的文件及文件夹列表
  60. NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  61. NSString *documentDir = [documentPaths objectAtIndex:0];
  62. NSError *error = nil;
  63. NSArray *fileList = [[NSArray alloc] init];
  64. //fileList便是包含有该文件夹下所有文件的文件名及文件夹名的数组
  65. fileList = [fileManager contentsOfDirectoryAtPath:documentDir error:&error];
  66. NSMutableArray *dirArray = [[NSMutableArray alloc] init];
  67. BOOL isDir = NO;
  68. //在上面那段程序中获得的fileList中列出文件夹名
  69. for (NSString *file in fileList)
  70. {
  71. NSString *path = [documentDir stringByAppendingPathComponent:file];
  72. [fileManager fileExistsAtPath:path isDirectory:(&isDir)];
  73. if (isDir)
  74. {
  75. [dirArray addObject:file];
  76. }
  77. isDir = NO;
  78. }
  79. NSLog(@"Every Thing in the dir:%@",fileList);
  80. NSLog(@"All folders:%@",dirArray);

NSFileManager和NSFileHandle(附:获取文件大小 )

//file文件操作NSFileManager常见的NSFileManager文件的方法:-(BOOL)contentsAtPath:path 从文件中读取数据-(BOOL)createFileAtPath:path contents:(BOOL)data attributes:attr 向一个文件写入数据-(BOOL)removeFileAtPath: path handler: handler 删除一个文件-(BOOL)movePath: from toPath: to handler: handler 重命名或移动一个文件(to可能已经存在)-(BOOL)copyPath:from toPath:to handler: handler 复制文件 (to不能存在)-(BOOL)contentsEqualAtPath:path1 andPath:path2 比较两个文件的内容-(BOOL)fileExistsAtPath:path 测试文件是否存在-(BOOL)isReadablefileAtPath:path 测试文件是否存在,且是否能执行读操作-(BOOL)isWritablefileAtPath:path 测试文件是否存在,且是否能执行写操作-(NSDictionary *)fileAttributesAtPath:path traverseLink:(BOOL)flag 获取文件的属性-(BOOL)changeFileAttributes:attr atPath:path 更改文件的属性NSFileManager对象的创建 :NSFileManager *fm;fm = [NSFileManager defaultManager];NSDictionary *attr =[fm fileAttributesAtPath: fname traverseLink: NO] ; //文件属性NSLog(@"file size is:%i bytes ",[[attr objectForKey:NSFileSize] intValue]);NSData *data =[fm contentsAtPath:@"filename"];//文件内容常见的NSFileManager目录的方法:-(NSString *)currentDirectoryPath 获取当前目录-(BOOL)changeCurrentDirectoryPath:path 更改当前目录-(BOOL)copyPath:from toPath:to handler:handler 复制目录结构,to不能已经存在-(BOOL)createDirectoryAtPath:path attributes:attr 创建目录-(BOOL)fileExistsAtPath:path isDirectory:(BOOL *)flag 测试文件是否为目录 (flag存储结构yes/no)-(NSArray *)contentsOfDirectoryAtPath:path 列出目录的内容-(NSDirectoryEnumerator *)enumeratorAtPath:path 枚举目录的内容-(BOOL)removeFileAtPath:path handler:handler 删除空目录-(BOOL)movePath:from toPath:to handler:handler 重命名或移动一个目录,to不能是已经存在的path= [fm currentDirectoryPath] ;NSArray *dirarray;NSDirectoryEnumerator *direnu;direnu = [fm enumeratorAtPath:path];NSLog(@"contents of %@\n",path);BOOL flag;while((path = [direnu nextObject])!=nil){NSLog(@"%@ ",path);[fm fileExistsAtPath:path isDirectory:&flag];if(flag == YES)[direnu skipDescendents]; //跳过子目录}path= [fm currentDirectoryPath] ;dirarray = [fm contentsOfDirectoryAtPath:path];NSLog(@"%@ ",dirarray);常用路径工具函数NSString * NSUserName(); 返回当前用户的登录名NSString * NSFullUserName(); 返回当前用户的完整用户名NSString * NSHomeDirectory(); 返回当前用户主目录的路径NSString * NSHomeDirectoryForUser(); 返回用户user的主目录NSString * NSTemporaryDirectory(); 返回可用于创建临时文件的路径目录常用路径工具方法-(NSString *) pathWithComponents:components 根据components中元素构造有效路径-(NSArray *)pathComponents 析构路径,获取路径的各个部分-(NSString *)lastPathComponent 提取路径的最后一个组成部分-(NSString *)pathExtension 路径扩展名-(NSString *)stringByAppendingPathComponent:path 将path添加到现有路径末尾-(NSString *)stringByAppendingPathExtension:ext 将拓展名添加的路径最后一个组成部分-(NSString *)stringByDeletingPathComponent 删除路径的最后一个部分-(NSString *)stringByDeletingPathExtension 删除路径的最后一个部分 的扩展名-(NSString *)stringByExpandingTildeInPath 将路径中的代字符扩展成用户主目录(~)或指定用户主目录(~user)-(NSString *)stringByResolvingSymlinksInPath 尝试解析路径中的符号链接-(NSString *)stringByStandardizingPath 通过尝试解析~、..、.、和符号链接来标准化路径-使用路径NSPathUtilities.htempdir = NSTemporaryDirectory(); 临时文件的目录名path = [fm currentDirectoryPath];[path lastPathComponent]; 从路径中提取最后一个文件名fullpath = [path stringByAppendingPathComponent:fname];将文件名附加到路劲的末尾extenson = [fullpath pathExtension]; 路径名的文件扩展名homedir = NSHomeDirectory();用户的主目录component = [homedir pathComponents]; 路径的每个部分NSProcessInfo类:允许你设置或检索正在运行的应用程序的各种类型信息(NSProcessInfo *)processInfo 返回当前进程的信息-(NSArray*)arguments 以NSString对象数字的形式返回当前进程的参数-(NSDictionary *)environment 返回变量/值对词典。描述当前的环境变量-(int)processIdentity 返回进程标识-(NSString *)processName 返回进程名称-(NSString *)globallyUniqueString 每次调用该方法都会返回不同的单值字符串,可以用这个字符串生成单值临时文件名-(NSString *)hostname 返回主机系统的名称-(unsigned int)operatingSystem 返回表示操作系统的数字-(NSString *)operatingSystemName 返回操作系统名称-(NSString *)operatingSystemVersionString 返回操作系统当前版本-(void)setProcessName:(NSString *)name 将当前进程名称设置为name过滤数组中的文件类型 : [fileList pathsMatchingExtensions:[NSArrayarrayWithObject:@"jpg"]];///////////////////////////////////////////////////////////////////////////////////////////////////////////基本文件操作NSFileHandle常用NSFileHandle方法(NSFileHandle *)fileHandleForReadingAtPath:path 打开一个文件准备读取(NSFileHandle *)fileHandleForWritingAtPath:path 打开一个文件准备写入(NSFileHandle *)fileHandleForUpdatingAtPath:path 打开一个文件准备更新(读取和写入)-(NSData *)availableData 从设备或通道返回可用数据-(NSData *)readDataToEndOfFile 读取其余的数据直到文件末尾(最多UINT_MAX字节)-(NSData *)readDataOfLength:(unsigned int)bytes 从文件读取指定数目bytes的内容-(void)writeData:data 将data写入文件-(unsigned long long) offsetInFile 获取当前文件的偏移量-(void)seekToFileOffset:offset 设置当前文件的偏移量-(unsigned long long) seekToEndOfFile 将当前文件的偏移量定位的文件末尾-(void)truncateFileAtOffset:offset 将文件的长度设置为offset字节-(void)closeFile 关闭文件

获取文件大小

Using the C FILE type:

int getFileSizeFromPath(char * path)
{
FILE * file;
int fileSizeBytes = 0;
file = fopen(path,"r");
if(file>0){
fseek(file, 0, SEEK_END);
fileSizeBytes = ftell(file);
fseek(file, 0, SEEK_SET);
fclose(file);
}
return fileSizeBytes;
}

or in XCode use the NSFileManager:

NSFileManager * filemanager = [[NSFileManager alloc]init];
if([filemanager fileExistsAtPath:[self getCompletePath] isDirectory:&isDirectory]){

NSDictionary * attributes = [filemanager attributesOfItemAtPath:[self getCompletePath] error:nil];

// file size
NSNumber *theFileSize;
if (theFileSize = [attributes objectForKey:NSFileSize])

_fileSize= [theFileSize intValue];
}

 

 

对于一个运行在iPhone得app,它只能访问自己根目录下得一些文件(所谓sandbox).

一个app发布到iPhone上后,它得目录结构如下:
[绍棠] iOS文件目录和文件操作 及NSFileManager的读写操作

1、其中得 app root 可以用 NSHomeDirectory() 访问到;

2、Documents 目录就是我们可以用来写入并保存文件得地方,一般可通过:

NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,
YES);NSString *documentsDirectory = [paths
objectAtIndex:0];

得到。

3、tmp 目录我们可以在里面写入一些程序运行时需要用得数据,里面写入得数据在程序退出后会没有。可以通过

NSString *NSTemporaryDirectory(void); 方法得到;

4、文件一些主要操作可以通过NSFileManage 来操作,可以通过 [NSFileManger defaultManger]
得到它得实例。

相关得一些操作:


创建一个目录:
比如要在Documents下面创建一个test目录,

NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

NSLog(@”%@”,documentsDirectory);

NSFileManager *fileManage = [NSFileManager
defaultManager];

NSString *myDirectory = [documentsDirectory
stringByAppendingPathComponent:@“test”];

BOOL ok = [fileManage createDirectoryAtPath:myDirectory
attributes:nil];


取得一个目录下得所有文件名:
(如上面的myDirectory)可用


NSArray *file = [fileManager subpathsOfDirectoryAtPath: myDirectory
error:nil];或

NSArray *files = [fileManager subpathsAtPath: myDirectory
];

读取某个文件:

NSData *data = [fileManger
contentsAtPath:myFilePath];//myFilePath是包含完整路径的文件名

或直接用NSData 的类方法:

NSData *data = [NSData dataWithContentOfPath:myFilePath];


保存某个文件:

可以用 NSFileManager的

- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data
attributes:(NSDictionary *)attr;

或 NSData 的

- (BOOL)writeToFile:(NSString *)path
atomically:(BOOL)useAuxiliaryFile;

- (BOOL)writeToFile:(NSString *)path
options:(NSUInteger)writeOptionsMask error:(NSError
**)errorPtr;


Phone文件系统:创建、重命名以及删除文件

NSFileManager中包含了用来查询单词库目录、创建、重命名、删除目录以及获取/设置文件属性的方法(可读性,可编写性等等)。

每个程序都会有它自己的沙盒,通过它你可以阅读/编写文件。写入沙盒的文件在程序的进程中将会保持稳定,即便实在程序更新的情况下。

如下所示,你可以在沙盒中定位文件目录:

//对于错误信息

NSError *error;

// 创建文件管理器

NSFileManager *fileMgr = [NSFileManagerdefaultManager];

//指向文件目录

NSString *documentsDirectory=
[NSHomeDirectory()

stringByAppendingPathComponent:@"Documents"];

//创建一个目录

[[NSFileManager defaultManager]
createDirectoryAtPath: [NSString stringWithFormat:@"%@/myFolder",
NSHomeDirectory()] attributes:nil];

创建一个文件

现在我们已经有了文件目录,我们就能使用这个路径在沙盒中创建一个新文件并编写一段代码:

// File we want to create in the documents
directory我们想要创建的文件将会出现在文件目录中

// Result is:
/Documents/file1.txt结果为:/Documents/file1.txt

NSString *filePath= [documentsDirectory

stringByAppendingPathComponent:@"file1.txt"];

//需要写入的字符串

NSString *str= @”iPhoneDeveloper Tips\nhttp://iPhoneDevelopTips,com“;

//写入文件

[str writeToFile:filePath
atomically:YES

encoding:NSUTF8StringEncoding
error:&error];

//显示文件目录的内容

NSLog(@”Documentsdirectory: %@”,

[fileMgr
contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);

我们为想要创建的文件构建一条路径(file1.txt),初始化一个字符串来写入文件,并列出目录。最后一行显示了在我们创建文件之后出现在文件目录下的一个目录列表:

对一个文件重命名

想要重命名一个文件,我们需要把文件移到一个新的路径下。下面的代码创建了我们所期望的目标文件的路径,然后请求移动文件以及在移动之后显示文件目录。

//通过移动该文件对文件重命名

NSString *filePath2= [documentsDirectory

stringByAppendingPathComponent:@"file2.txt"];

//判断是否移动

if ([fileMgr moveItemAtPath:filePath toPath:filePath2
error:&error] != YES)

NSLog(@”Unable to move file: %@”, [error
localizedDescription]);

//显示文件目录的内容

NSLog(@”Documentsdirectory: %@”,

[fileMgr
contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);

在移动了文件之后,输出结果应该如下图所示:

删除一个文件

为了使这个技巧完整,让我们再一起看下如何删除一个文件:

//在filePath2中判断是否删除这个文件

if ([fileMgr removeItemAtPath:filePath2
error:&error] != YES)

NSLog(@”Unable to delete file: %@”, [error
localizedDescription]);

//显示文件目录的内容

NSLog(@”Documentsdirectory: %@”,

[fileMgr
contentsOfDirectoryAtPath:documentsDirectoryerror:&error]);

一旦文件被删除了,正如你所预料的那样,文件目录就会被自动清空:

这些示例能教你的,仅仅只是文件处理上的一些皮毛。想要获得更全面、详细的讲解,你就需要掌握NSFileManager文件的知识。







在开发iPhone程序时,有时候要对文件进行一些操作。而获取某一个目录中的所有文件列表,是基本操作之一。通过下面这段代码,就可以获取一个目录内的文件及文件夹列表。


复制代码

  1. NSFileManager *fileManager = [NSFileManager
    defaultManager];

    //在这里获取应用程序Documents文件夹里的文件及文件夹列表

    NSArray
    *documentPaths =
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
    NSUserDomainMask, YES);

    NSString
    *documentDir = [documentPaths objectAtIndex:0];

    NSError
    *error = nil;

    NSArray
    *fileList = [[NSArray alloc] init];

    //fileList便是包含有该文件夹下所有文件的文件名及文件夹名的数组

    fileList
    = [fileManager contentsOfDirectoryAtPath:documentDir
    error:&error];




以下这段代码则可以列出给定一个文件夹里的所有子文件夹名


复制代码

  1. NSMutableArray *dirArray = [[NSMutableArray alloc] init];

    BOOL
    isDir = NO;

    //在上面那段程序中获得的fileList中列出文件夹名

    for
    (NSString *file in fileList) {

    NSString
    *path = [documentDir
    stringByAppendingPathComponent:file];

    [fileManager
    fileExistsAtPath:path
    isDirectory:(&isDir)];

    if
    (isDir) {

    [dirArray