NSFileManager类

简介: NSFileManager类

文件操作



基于NSFileManager类,允许用户对文件进行基本操作。这些操作包括:创建新的文件、读取文件、对文件进行复制、移动以及删除等,同时还可以对文件的一些常规属性进行读取以及修改。


1.基本概念


在学习NSFileManager类的相关属性和方法之前,需要提前了解并掌握如下几个与文件相关的基本概念。


路径Path:在使用NSFileManager类对文件进行操作时,经常需要使用到路径的概念,路径可以理解为文件的物理存储路径+文件名称的组合,每个路径名都是一个NSString类型的对象。


属性Attr:文件的属性是一个NSDictionary类型的对象,文件属性定义在Foundation/NSFileManager.h文件中,有二十余个。


错误err:一个指向NSError对象的指针,能提供有关文件操作更多的错误信息,如果err被置为nil,那么就会采取默认的错误处理行为。


2.基本操作


在使用NSFileManager类时,需要实例化一个NSFileManager类的对象,然后对指定路径Path上的文件进行一些操作。下方的代码演示了如何获取目录,如何获取路径(这里要注意区分路径和目录的区别),如何实例化NSFileManager类,以及如何判断一个文件是否存在。


首先在计算机的桌面上创建一个myfile.txt文件,可以打开终端,执行如下命令:


cd $HOME/Desktop
touch myfile.txt


文件准备完成后,在main()函数中添加下方的代码。需要注意的是:文件的路径可以通过两种方式来获取,第一种是直接给出绝对路径;另外一种是通过NSSearchPathForDirectoriesInDomains()函数来获取。


//目录路径Path:绝对路径
NSString *directoryPath = @"/Users/shixin/Desktop";
//通过NSSearchPathForDirectoriesInDomains()函数获取路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
NSString *desktopPath = [paths objectAtIndex:0];
//文件路径
//拼接文件名称需要使用stringByAppendingPathComponent:方法
NSString *filePath1 = [directoryPath stringByAppendingPathComponent:@"myfile.txt"];
NSString *filePath2 = [desktopPath stringByAppendingPathComponent:@"myfile.txt"];
//实例化NSFileManager对象
NSFileManager *fm = [NSFileManager defaultManager];
//判断路径文件是否存在
if ([fm fileExistsAtPath:filePath1]) {
   NSLog(@"myfile.txt exist in filePath!");
}
if ([fm fileExistsAtPath:filePath2]) {
   NSLog(@"myfile.txt exist in desktopPath!");
}


运行结果如图4-24所示。


2466108-4ac02a0494c9c2c7.webp.jpg


图4-24 运行结果


3.文件的复制、移动、重命名与删除


在开发过程中,涉及对文件进行复制、移动、重命名以及删除等操作,在NSFileManager类中也提供了对应的方法。


复制文件。


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


移动文件。该方法除了移动文件外,还可以用于文件改名。


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


删除文件。


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


示例:


//目录路径Path:绝对路径
NSString *directoryPath = @"/Users/shixin/Desktop";
//文件路径
NSString *filePath = [directoryPath stringByAppendingPathComponent:@"myfile.txt"];
//实例化NSFileManager对象
NSFileManager *fm = [NSFileManager defaultManager];
//复制文件
NSString *copyFilePath = [directoryPath stringByAppendingPathComponent:@"myfilecopy.txt"];
if ([fm fileExistsAtPath:copyFilePath] == NO) { //文件不存在,则创建
    if ([fm copyItemAtPath:filePath toPath:copyFilePath error:nil]) {
        NSLog(@"file copy success!");
    }
}
//移动文件:除了移动文件外,还可以用于文件改名
NSString *moveFilePath = [directoryPath stringByAppendingPathComponent:@"myfileNEWcopy.txt"];
if ([fm fileExistsAtPath:filePath]) { //文件存在,则移动文件到moveFilePath
    if ([fm moveItemAtPath:filePath toPath:moveFilePath error:nil]) {
        NSLog(@"file move success");
    }
}
//删除文件
if ([fm removeItemAtPath:moveFilePath error:nil]) {
    NSLog(@"file remove success");
}


可以看到myfile.txt文件被成功地复制、移动、重命名以及删除。


2021-07-15 10:40:30.958447+0800 文件操作[22783:496013] file copy success!
2021-07-15 10:41:07.300241+0800 文件操作[22783:496013] file move success
2021-07-15 10:41:21.445544+0800 文件操作[22783:496013] file remove success


4.获取与修改文件属性


每个文件都有一些其自身属性,例如:文件大小、文件类型、文件所有者等,可以使用NSFileManager来读取以及修改指定路径上文件的属性。


获取文件属性:可以使用attributesOfItemAtPath:方法来获取文件的属性,返回值是一个字典,其中存储了该目标文件的属性。下面的代码中,通过attributesOfItemAtPath:方法获取了一个文件的所有属性,并且打印了文件的NSFileOwnerAccountName以及NSFileCreationDate两个属性。


//目录路径Path:绝对路径
NSString *directoryPath = @"/Users/shixin/Desktop";
//文件路径
NSString *filePath = [directoryPath stringByAppendingPathComponent:@"myfile.txt"];
//实例化NSFileManager对象
NSFileManager *fm = [NSFileManager defaultManager];
NSDictionary *fileAttr = [fm attributesOfItemAtPath:filePath error:nil];
NSLog(@"file owner name: <%@>, file create date: <%@>", fileAttr[NSFileOwnerAccountName], fileAttr[NSFileCreationDate]);


运行结果


2021-07-15 10:55:16.418124+0800 文件操作[23043:504342] file owner name: <shixin>, file create date: <Thu Jul 15 10:07:38 2021>


文件的属性列表可以在Foundation/NSFileManager.h文件中查询,常用的一些属性如下所示。


NSFileAttributeKey const NSFileType; //文件类型
NSFileAttributeKey const NSFileSize; //文件大小
NSFileAttributeKey const NSFileCreationDate; //文件创建日期
NSFileAttributeKey const NSFileModificationDate; //文件修改日期
NSFileAttributeKey const NSFileOwnerAccountName; //文件所有人


更改文件属性:使用setAttributes:ofItemAtPath:error:方法来设置文件属性,在调用该方法之前,需要把希望改变的属性封装在一个字典中。如下所示,下方的代码更改了文件的创建时间NSFileCreationDate:


//目录路径Path:绝对路径
NSString *directoryPath = @"/Users/shixin/Desktop";
//文件路径
NSString *filePath = [directoryPath stringByAppendingPathComponent:@"myfile.txt"];
//实例化NSFileManager对象
NSFileManager *fm = [NSFileManager defaultManager];
//更改文件属性
NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSDate distantFuture], NSFileCreationDate, nil];
[fm setAttributes:attrDict ofItemAtPath:filePath error:nil];
NSDictionary *fileAttr = [fm attributesOfItemAtPath:filePath error:nil];
NSLog(@"file create date:<%@>", fileAttr[NSFileCreationDate]);


运行结果


2021-07-15 11:17:16.424991+0800 文件操作[23643:524814] file create date:<Sat Apr 12 07:47:16 2262>


目录操作



NSFileManager类也提供了用于处理目录的一些方法,这些方法与处理普通文件的方法类似。


1.获取与变更当前目录


与在操作系统中对文件操作类似,用户经常需要获取当前所在的目录,并且可以通过前进/后退等操作来改变当前的操作目录。在NSFileManager类中也提供了获取与变更当前目录的方法。


获取当前目录。


@property (readonly, copy) NSString *currentDirectoryPath;


变更当前目录。


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


2.目录的创建、重命名与删除


与创建文件类似,目录也可以进行创建,同时可以对目录进行移动、重命名以及删除,在NSFileManager类中也提供了对应的方法。

创建目录。


- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary<NSFileAttributeKey, id> *)attributes error:(NSError **)error;


重命名/移动目录。


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


删除目录。


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


枚举目录中的内容



查看某个文件夹中的文件列表,在文件操作中是被高频使用的,在DOS中可以使用DIR命令,在Linux中可以使用ls命令,在iOS开发中,可以使用enumeratorAtPath:方法以及contentsOfDirectoryAtPath:方法,这两个方法都可以完成对指定目录的文件列表枚举,但使用中稍有差别。


1.enumeratorAtPath:方法


当使用enumeratorAtPath:方法时,一次可以枚举指定目录中的所有文件,包括子目录中的文件。该方法的返回值类型为一个NSDirectoryEnumerator类型的对象,可以使用nextObject方法来取出其中的值。


- (nullable NSDirectoryEnumerator<NSString *> *)enumeratorAtPath:(NSString *)path;


2.contentsOfDirectoryAtPath:方法


当使用contentsOfDirectoryAtPath:方法时,也可以列出当前目录中的文件和文件夹名称,但子文件夹中的内容并不显示。该方法的返回值是一个NSArray类型的数组,因此可以使用for in循环来遍历其中的对象。


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


对比上面使用enumeratorAtPath:方法的代码,可以看到子目录中的文件并不显示。


文件的读取与写入



当对文件进行操作时,有时需要读取文件的内容,然后把文件的内容放到内存中的一块缓冲区以供后续使用。另外,有时还需要把数据缓冲区中的内容写入文件中进行保存。这两种操作就涉及文件的读取以及写入操作。文件的读取以及写入,除了使用NSFileManager类之外,还需要使用NSData类所提供的缓冲区。


1.文件内容的读取


在NSFileManager类中,提供了contentsAtPath:方法,可以读取指定目录中的文件,同时返回值是一个NSData类型的对象。


- (nullable NSData *)contentsAtPath:(NSString *)path;


2.数据写入文件


对于已经保存在缓冲区中的NSData对象,可以写入文件。常用的有两种方法,既可以使用NSFileManager类提供的方法,也可以使用NSData类提供的方法。


方法一:使用NSData类的writeToFile方法。


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


方法二:使用NSFileManager类提供的createFileAtPath方法。


- (BOOL)createFileAtPath:(NSString *)path contents:(nullable NSData *)data attributes:(nullable NSDictionary<NSFileAttributeKey, id> *)attr;


3.示例代码


下方的示例代码演示了对文件内容的读取以及解码(NSData转NSString),以及把NSData对象写入文件进行保存的过程。


首先在桌面上创建一个myfile.txt文件,并在文件中输入一些文字内容。在main()函数中,编写如下代码。


//实例化NSFileManager对象
NSFileManager *fm = [NSFileManager defaultManager];
//目录路径Path:绝对路径
NSString *path = @"/Users/shixin/Desktop";
NSString *filePath = [path stringByAppendingPathComponent:@"myfile.txt"];
NSData *fileData = [fm contentsAtPath:filePath];
NSString *fileContent = [[NSString alloc]initWithData:fileData encoding:NSUTF8StringEncoding];
NSLog(@"%@",fileContent);
//把NSData写入文件
//方法一
NSString *newFilePath1 = [path stringByAppendingPathComponent:@"myNewFile1.txt"];
if ([fileData writeToFile:newFilePath1 atomically:YES]) {
   NSLog(@"使用writeToFile:方法写入成功!");
}
//方法二
NSString *newFilePath2 = [path stringByAppendingPathComponent:@"myNewFile2.txt"];
if ([fm createFileAtPath:newFilePath2 contents:fileData attributes:nil]) {
   NSLog(@"使用createFileAtPath:方法写入成功!");
}


运行结果


2021-07-15 14:21:19.668551+0800 文件操作[27830:635428] www.99ios.com
2021-07-15 14:21:19.669725+0800 文件操作[27830:635428] 使用writeToFile:方法写入成功!
2021-07-15 14:21:19.670312+0800 文件操作[27830:635428] 使用createFileAtPath:方法写入成功!


摘自《iOS开发:从零基础到精通》

目录
相关文章
|
7月前
|
Java
JAVARandom类
JAVARandom类
56 0
C++类的一些特殊知识
C++类的一些特殊知识
|
6月前
abject类的使用(11.4)
abject类的使用(11.4)
|
7月前
|
算法 Java Serverless
JAVAMath类
JAVAMath类
41 0
|
7月前
|
Java
JAVASystem类
JAVASystem类
33 0
|
7月前
|
存储 编译器 C++
c++类全面讲解
前言 这次主要讲类的基础、构造函数与析构函数的使用,以及继承和多态。
127 0
13.3.1 QBluetoothSocket类介绍
13.3.1 QBluetoothSocket类介绍
138 0
13.3.1 QBluetoothSocket类介绍
|
程序员 C++ 编译器
c++模板类
理解编译器的编译模板过程 如何组织编写模板程序 前言常遇到询问使用模板到底是否容易的问题,我的回答是:“模板的使用是容易的,但组织编写却不容易”。看看我们几乎每天都能遇到的模板类吧,如STL, ATL, WTL, 以及Boost的模板类,都能体会到这样的滋味:接口简单,操作复杂。
1004 0
|
C++ 编译器 程序员