iOS 内存
这是我去年整理的一片文章,粘贴上来,希望对大家有所帮助,现在还不会操作简书,不知道怎么把代码块变颜色,看着很费劲,有时间会考虑改一下
(一) 沙盒路径
l 每一个APP都有一个存储空间,就是沙盒。APP之间不能相互通信。沙盒根目录结构:
l Bundle Container目录包含应用程序包。
l Data Container目录包含app和用户的数据,可以进一步分为几个子目录,以便app对数据进行分类。
l 应用程序还可以在运行时请求访问如iCloud容器一类目录。
Documents、Library、temp、SystemData
l 路径如下
// 1.捆绑包目录
NSLog(@"bundlePath %@",[NSBundle mainBundle].bundlePath)
// 获取沙盒主目录路径
NSString *homeDir = NSHomeDirectory();
// 模拟器下的路径
/Users/caoguofang/Library/Developer/CoreSimulator/Devices/42BB91D8-7698-4941-AE65-6D3FA621A8E7/data/Containers/Data/Application/D06AB79E-DFDD-443E-B551-33EB854B8C00
// 真机下的路径
/var/mobile/Containers/Data/Application/8194D1EB-4026-49F6-ADAD-458355533828
// 应用的标识再往下就是沙盒了.系统生成.
(3AE2AB9E-053B-41BF-B3D0-688F96A0D2F1),
(8194D1EB-4026-49F6-ADAD-458355533828)
*注:每次编译代码会生成新的沙盒,注意是编译不是启动,所以模拟器或者针剂运行你每次运行所得到的沙盒路径都是不一样的,就是上面提到的标识符不一样,正式版app真机启动杀死,不会生成新的沙盒
*注:直接拖进去的资源文件,直接拖进了Bundle Container里,在捆绑包内是可以看到的,但是在Assets.xcassets里面就不会被看到,图片被压缩到asset.car
l 获取沙盒文件
1. 模拟器:从项目中打印出路径,从电脑上前往文件夹就可以获取
2. 真机运行获取当前运行app的沙盒路径的Document文件,其实开发当中需要做的配置就一步, 剩下的是引导用户怎么去使用文件共享功能,在Info.plist 文件中添加 UIFileSharingEnabled 这个key,并设置该值为YES即可,在填写完UIFileSharingEnabled并回车后,发现自动更正为Application supports iTunes file sharing ,将值设置为YES。
3. 在Xcode的菜单中,window->devices中选中你的真机,可以看到你真机调试的app列表,选中某个,可以对这个app的沙盒进行下载和替换
l 一、Documents
这个目录用于存储用户数据或其它应该定期备份的信息。
// 获取Documents目录路径
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
1. 此文件夹是默认备份的,备份到iCloud
注:iCloud的备份,会通过Wi-Fi每天自动备份用户iOS设备。
1.app的home目录下的所有东西都会被备份,除了应用Bundle本身、缓存目录和temp目录。
2.已购买的音乐、应用、书籍、Camera Roll、设备设置、主屏幕、App组织、消息、铃声也都会被备份。
3.由于备份通过无线进行,并且为每个用户存储在iCloud中,应用需最小化自己存储的数据数量。
4.大文件会延长备份时间,并且消耗用户的可用iCloud空间。
2. 大文件要做非备份设置(如视频) 审核的时候会被拒(大文件会延长备份时间,并且消耗用户的可用iCloud 空间。)
// 非备份设置代码如下
// 需要导入
#include
- (BOOL)addShipBackUpAttributeToUrl:(NSString *)url {
NSURL *itemUrl = [NSURL URLWithString:url];
const char *filePath = [[itemUrl path] fileSystemRepresentation];
const char* attrName = "com.apple.MobileBackup";
u_int8_t attrValue = 1;
int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
return result == 0;
}
3. 此目录储存规则
关键数据
用户生成的数据,应用程序不能重新创建的数据。
应该存放在<Application_Home>/Documents目录下,并且不应该标记为"do not backup"属性。
关键数据在低存储空间时也会保留,而且会被iCloud或iTunes备份。
4. 经常存储的一些东西
1.APP的数据库表.
2.必要的一些图标本地缓存.
3.重要的plist文件,如当前登录人的信息.
l 二、Library
里面包括两个文件夹:Perferences、Caches,也可以自己创建子文件。除Caches以外,都会被iTunes备份
/Preferences:包含应用程序的偏好设置文件,不能直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
/Caches:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息,保存可以重新下载或者重新生成的数据,而且没有这些文件也不会妨碍用户离线使用应用的功能。适合存储体积大,不需要备份的非重要数据。当访问网络时系统自动会把访问的url,以数据库的方式存放在此目录下面.
// 获取Library的目录路径
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
// 获取Caches目录路径
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
l 三、tmp
临时文件夹(系统会不定期删除里面的文件)
// 获取tmp目录路径
NSString *tmpDir = NSTemporaryDirectory();
应用需要写到本地存储,内部使用的临时数据,但不需要长期保留使用。
临时数据应该保存在<Application_Home>/tmp目录。
系统可能会清空该目录下的数据,iTunes或iCloud也不会对其进行备份。
应用在不需要使用这些数据时,应该尽快地删除临时数据,以避免浪费用户的存储空间。
l 四、SystemData
新加入的一个文件夹, 存放系统的一些东西、
NSFileManager和NSFilehandle
概念:
1. NSFileManager 是 Foundation 框架中用来管理和操作文件、目录等文件系统相关内容的类。
2. NSFileHandle类:它需要配合NSFileManager文件管理类,对文件内容进行操作,写入数据、读取数据
1. 对文件的处理
1.1 拿到沙盒的Document路径(通常默认放在这个路径下)
// 拿到沙盒路径
-(NSString*)getDocumentPath
{
// @expandTilde 是否覆盖
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
1.2 创建文件夹,并且判断是否创建成功
NSString *documentsPath =[self getDocumentPath];
NSFileManager *fileManager = [NSFileManager defaultManager];// NSFileManager 是 Foundation 框架中用来管理和操作文件、目录等文件系统相关联内容的类。
NSString * testDirectory = [documentsPath stringByAppendingPathComponent:@"日记"];
BOOL res = [fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];
if (res) {
NSLog(@"文件夹创建成功");
}else
{
NSLog(@"文件夹创建失败");
}
注:根据苹果官方文档介绍,这个参数可以设置所创建目录所属的用户和用户组,目录的访问权限和修改时间等。如果设置为nil,那么所创建目录的属性则采用系统默认设置,一般会将目录的用户设置为root,访问权限设置为0755,这样就导致其他用户向这个目录写入时失败。
attributes参数是一个字典类型。查看苹果官方文档的介绍,可以看到在NSFileManager.h头文件定义了很多常量字符串,用于作为attributes字典的键,针对于这个接口的键主要包括下面几个:
l NSFileType
文件属性字典中的关键字,其值指示文件的类型。
注:(NSFileAttributeType :NSFileTypeDirectory、NSFileTypeRegular、NSFileTypeSymbolicLink、NSFileTypeSocket、NSFileTypeCharacterSpecial、NSFileTypeBlockSpecial、NSFileTypeUnknown)
l NSFileExtensionHidden
文件后缀是否隐藏
l NSFileModificationDate
文件修改的时间
l NSFileSize(不可更改)
文件或者文件夹的大小,注意单位是byte
l NSFileAppendOnly
这个键的值需要设置为一个表示布尔值的NSNumber对象,表示创建的目录是否是只读的。
l NSFileCreationDate
这个键的值需要设置为一个NSDate对象,表示目录的创建时间。
l NSFileOwnerAccountName
这个键的值需要设置为一个NSString对象,表示这个目录的所有者的名字。
l NSFileGroupOwnerAccountName
这个键的值需要设置为一个NSString对象,表示这个目录的用户组的名字。
l NSFileGroupOwnerAccountID
这个键的值需要设置为一个表示unsigned int的NSNumber对象,表示目录的组ID。
l NSFileModificationDate
这个键的值需要设置一个NSDate对象,表示目录的修改时间。
l NSFileOwnerAccountID
这个键的值需要设置为一个表示unsigned int的NSNumber对象,表示目录的所有者ID。
l NSFilePosixPermissions
这个键的值需要设置为一个表示short int的NSNumber对象,表示目录的访问权限。
l NSFileDeviceIdentifier
文件所在驱动器的标示符
l NSFileSystemNumber
文件系统属性字典中的键,其值指示文件系统的文件系统编号
l NSFileSystemFileNumber
文件属性字典中的键,其值指示文件的文件系统文件号。
l NSFileHFSCreatorCode
文件属性字典中的关键字,其值指示文件的HFS创建者代码。
l NSFileHFSTypeCode
文件属性字典中的关键字,其值指示文件的HFS类型代码。
l NSFileImmutable
该方法用于返回文件是否可以改变。
l NSFileBusy
文件是否繁忙
l NSFileProtectionKey(这个扩展属性标示着文件的保护等级,相对应的值也是NSString类型的,是一个在锁屏状态下造成影响的属性,没有提供attributes的字典时,创建的文件夹的权限属性是不确定的,跟随当前进程的umask而定)
l NSFileProtectionNone:文件没有设置任何保护,随时可以读写。
l NSFileProtectionComplete:最完备等级的保护,文件以加密形式写在磁盘中,当设备(iPhone/iPad)在Locked(锁屏,还是带密码的那种)状态或者booting(正在开机)时无法读写。
l NSFileProtectionCompleteUnlessOpen:也是加密写在磁盘中,区别与上一个的事,文件在锁屏状态下可以被创建,但是不能关闭文件,一旦关了它,在解锁之前你是不可以做任何操作的。解锁之后,你可以正常操作文件,即使这个时候用户再次锁上设备。虽然没有被写入或读取,这里在创建或打开文件时也有一点小小的性能损失。更缓和的策略是在设备未锁住时将文件属性设为NSFileProtectionComplete。
l NSFileProtectionCompleteUntilFirstUserAuthentication:文件以加密形式存储在磁盘上,未开启机器时是不可以存取的,在用户第一次解锁设备之后(理解为开机后第一次解锁),你的app可以使用这个文件即使用户锁屏了也没关系。
l NSFileReferenceCount
这个键的值需要设置为一个表示unsigned long的NSNumber对象,表示目录的引用计数,即这个目录的硬链接数。
l NSFileSystemSize
系统内存(unsignedLongLongValue)
uint64_t totalSpace = 0.0f;
uint64_t totalFreeSpace = 0.0f;
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
totalSpace = [fileSystemSizeInBytes floatValue];
totalFreeSpace = [freeFileSystemSizeInBytes floatValue];
NSLog(@"Memory Capacity of %llu GB with %llu GB Free memory available.", ((totalSpace/1024ll)/1024ll/1024ll), ((totalFreeSpace/1024ll)/1024ll/1024ll));
打印结果:2019-08-13 09:41:29.839229+0800 ShunDaoDev[8769:66540] Memory Capacity of 233 GB with 72 GB Free memory available.
l NSFileSystemFreeSize
系统剩余内存(unsignedLongLongValue)
l NSFileSystemNodes
文件系统属性字典中的关键字,其值指示文件系统中的节点数。
l NSFileSystemFreeNodes
文件系统属性字典中的关键字,其值指示文件系统中的空闲节点数。
节点:理解为一个服务或者一个服务器,同一套逻辑相同的程序,在服务器里A运行了一个实例,在B里又运行了一个实例,而且他们又是集群的,那就可以理解为 节点A 节点B。就像玩游戏,一个游戏里有广东区,上海区,就可以称之为广东节点,上海节点。主要用于集群分流
1.3创建文件,并判断文件是否创建
NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];
BOOL res1 = [fileManager createFileAtPath:testPath contents:nil attributes:nil];
if (res1) {
NSLog(@"文件创建成功: %@" ,testPath);
}else
{
NSLog(@"文件创建失败");
}
1.4写入数据,并判断文件是否存在
NSString * str = @"你是一位好同志";
BOOL res2 = [str writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (res2) {
NSLog(@"文件写入成功");
}else
{
NSLog(@"文件写入失败");
}
// 判断文件是否存在
if ([fileManager fileExistsAtPath:testPath]) {
NSLog(@" 是否存在 ");
}
1.5追加写入内容
// 追加内容
NSFileHandle * handFile = [NSFileHandle fileHandleForUpdatingAtPath:testPath]; //NSFileHandle类:它需要配合NSFileManager文件管理类,对文件内容进行操作,写入数据、读取数据。
[handFile seekToEndOfFile];// 文件光标移动末尾
NSString * str1 = @"追加内容";// 追加内容
NSData * data = [str1 dataUsingEncoding:NSUTF8StringEncoding];// 转换文件格式
[handFile writeData:data];// 写入文件
[handFile closeFile];// 关闭
1.6判断文件是否删除
// 删除文件
BOOL isOK = [fileManager removeItemAtPath:testPath error:nil];
if (isOK) {
NSLog(@"-- 成功删除---");
}
1.7拷贝文件
// 拷贝文件
NSString *targetPath = [testDirectory stringByAppendingPathComponent:@"test1.txt"]; //目标文件路径
[fileManager copyItemAtPath:testPath toPath:targetPath error:nil]; // 拷贝文件
1.8移动文件
[fileManager moveItemAtPath:testPath toPath:targetPath error:nil];
1.9读取文件
NSString * content = [NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"拿到文章的内容 -- %@",content);
1.10 计算文件大小
// 计算文件大小
- (unsigned long long)fileSizeAtPath:(NSString *)filePath {
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:filePath];
if (isExist) {
unsigned long long fileSize = [[fileManager attributesOfItemAtPath:filePath error:nil] fileSize];
return fileSize;
} else {
NSLog(@"file is not exist");
return 0;
}
}
1.11计算文件夹大小
// 计算整个文件夹中所有文件大小
- (unsigned long long)folderSizeAtPath:(NSString*)folderPath {
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:folderPath];
if (isExist) {
NSEnumerator *childFileEnumerator = [[fileManager subpathsAtPath:folderPath] objectEnumerator];
unsigned long long folderSize = 0;
NSString *fileName = @"";
while ((fileName = [childFileEnumerator nextObject]) != nil){
NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
folderSize += [self fileSizeAtPath:fileAbsolutePath];
}
return folderSize / (1024.0 * 1024.0);
} else {
NSLog(@"file is not exist");
return 0;
}
}
2. NSFileManager 里其他的方法
2.1
- (nullable NSArray<NSURL *> *)mountedVolumeURLsIncludingResourceValuesForKeys:(nullableNSArray<NSURLResourceKey> *)propertyKeys options:(NSVolumeEnumerationOptions)options API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
返回到NSURLS中的NSArray,查找计算机上可用的已装入卷。可以申请的属性键可在<基金会/NSURL.H>中获得(移动硬盘或者u盘的地址)
2.2
- (void)unmountVolumeAtURL:(NSURL *)url options:(NSFileManagerUnmountOptions)mask completionHandler:(void (^)(NSError * _Nullable errorOrNil))completionHandler API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos);
启动卸载卷宗的进程
2.3
- (nullable NSArray<NSURL *> *)contentsOfDirectoryAtURL:(NSURL *)url includingPropertiesForKeys:(nullable NSArray<NSURLResourceKey> *)keys options:(NSDirectoryEnumerationOptions)mask error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
简单返回文件夹内容的URL
NSURL *folderURL = [NSURL fileURLWithPath:@"/Applications/"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *folderContents = [fileManager
contentsOfDirectoryAtURL:folderURL
includingPropertiesForKeys:nil
options:0
error:&error];
NSLog(@"%@",folderContents);
打印结果:
2.4
- (NSArray<NSURL *> *)URLsForDirectory:(NSSearchPathDirectory)directory inDomains:(NSSearchPathDomainMask)domainMask API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
实例方法允许你在IOS的文件系统中搜索指定的目录,特别是在你应用的沙箱中
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(returnRefreshData) name:AdvertRefreshNotification object:nil];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSArray *urls = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
if ([urls count] > 0) {
NSURL *documentsFolder = urls[0];
NSLog(@"%@",documentsFolder);
}else{
NSLog(@"Could not find the Documents folder");
}
打印结果:
2.5
- (nullable NSURL *)URLForDirectory:(NSSearchPathDirectory)directory inDomain:(NSSearchPathDomainMask)domain appropriateForURL:(nullable NSURL *)url create:(BOOL)shouldCreate error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
NSURL *url = [NSURL URLWithString:@"/Users/caoguofang/Desktop/haha.doc"];
NSFileManager *nfManager = [NSFileManager defaultManager];
NSURL *url1 = [nfManager URLForDirectory:NSItemReplacementDirectory
inDomain:NSUserDomainMask
appropriateForURL:url
create:YES
error:nil];
NSLog(@"%@",url1);
查找符合条件的文件目录,该方法不但可以获得标准系统目录,还可以用来创建临时路径
当在directory参数中设置为NSItemReplacementDirectory以及domain参数中设置为 NSUserDomainMask的时候,appropriateForURL这个参数才会起效.当创建一个临时目录的时候,shouldCreate是被忽略的,并且会一直创建目录.
2.6
- (BOOL)getRelationship:(NSURLRelationship *)outRelationship ofDirectoryAtURL:(NSURL *)directoryURL toItemAtURL:(NSURL *)otherURL error:(NSError **)error API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *url1 = [NSURL URLWithString:@"/Users/caoguofang/Desktop"];
NSURL *url2 = [NSURL URLWithString:@"/Users/caoguofang/Desktop/苹果简介.html"];
NSURLRelationship ship = NSURLRelationshipContains;
BOOL ifContaint = [fileManager getRelationship:&ship ofDirectoryAtURL:url1 toItemAtURL:url2 error:nil];
if (ifContaint)
{
NSLog(@"包含");
}else {
NSLog(@"不包含");
}
判断一个文件地址是否包含另一个文件地址,前一个地址是够包含另一个地址
2.7
- (BOOL)getRelationship:(NSURLRelationship *)outRelationship ofDirectory:(NSSearchPathDirectory)directory inDomain:(NSSearchPathDomainMask)domainMask toItemAtURL:(NSURL *)url error:(NSError **)error API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
NSFileManager *nfManager = [NSFileManager defaultManager];
NSURL *url1 = [nfManager URLForDirectory:NSAllApplicationsDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:NO
error:nil];
NSLog(@"%@",url1);
NSURLRelationship ship = NSURLRelationshipContains;
BOOL ifExit = [nfManager getRelationship:&ship ofDirectory:NSAllApplicationsDirectory inDomain:NSUserDomainMask toItemAtURL:url1 error:nil];
判断一个系统级目录是否包含一个文件,比如判断一个文件是否存在在废纸篓里。这个和上面的不同之处:上面是判断随便一个文件地址是否包含另一个文件地址,而这个是判断一个系统级目录是否包含一个文件地址,取值取的系统级目录枚举值
2.8
- (BOOL)createDirectoryAtURL:(NSURL *)url withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary<NSFileAttributeKey, id> *)attributes error:(NSError **)error API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *str = @"Users/caoguofang/Desktop/创建文件";
BOOL ifMake = [fileManager createDirectoryAtURL:[NSURL URLWithString:str] withIntermediateDirectories:str attributes:nil error:nil];
创建指定路径的文件,withIntermediateDirectories这个字段,如果是写的YES ,那即使写的文件上层目录不存在也会重新自动创建一个,如果是NO,如果上层目录不存在,将不会自动创建上层,返回nil
2.9
- (nullable NSArray<NSString *> *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *array = [fileManager contentsOfDirectoryAtPath:@"/Users/caoguofang/Desktop/" error:nil];
查找当前目录下的子文件夹,以数组形式返回
2.10
- (nullable NSArray<NSString *> *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *array2 = [fileManager subpathsOfDirectoryAtPath:@"/Users/caoguofang/Desktop/" error:nil];
递归遍历所有的文件及其子文件
2.11
- (nullable NSDictionaryid> *)attributesOfFileSystemForPath:(NSString *)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *dicAttr = [fileManager attributesOfItemAtPath:@"/Users/caoguofang/Desktop/苹果简介.html" error:nil];
获得文件属性
打印结果
2.12
- (nullable NSDictionary *)attributesOfFileSystemForPath:(NSString*)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [NSFileManager defaultManager];
NSDictionary *dicAttr2 = [fileManager attributesOfFileSystemForPath:@"/Users/caoguofang/Desktop/苹果简介.html" error:nil];
获取整个文件系统的属性
打印结果
- (BOOL)createSymbolicLinkAtPath:(NSString *)path withDestinationPath:(NSString *)destPath error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); 2.13
NSString *path1 = @"/Users/caoguofang/Desktop/apple.html";
NSURL *url2 = [NSURL fileURLWithPath:@"/Users/caoguofang/Desktop/haha.rtf"];
NSError *error;
BOOL resultU2 = [fileManager createSymbolicLinkAtURL:url2 withDestinationURL:[NSURL fileURLWithPath:path1] error:&error];
if (resultU2)
{
NSLog(@"链接创建成功");
}else {
NSLog(@"创建失败:%@",error);
}
创建一个文件的快捷方式,URL2 是创建的快捷方式(创建之前,URL2这个地址应该是不存在的),是path1 这个地址所指的文件的快捷方式
打印结果
- (nullable NSString *)destinationOfSymbolicLinkAtPath:(NSString *)path error:(NSError**)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));2.14
NSString *carrierPListSymLinkPath = @"/Users/caoguofang/Desktop/haha.rtf";
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSString *carrierPListPath = [fm destinationOfSymbolicLinkAtPath:carrierPListSymLinkPath error:&error];
返回指向的项的符号链接的路径。(打印出快捷方式所指的真实路径)
打印结果
2.15
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSString *carrierPListSymLinkPath = @"/Users/caoguofang/Desktop/新建上层文件夹";
NSString *carrierPListSymLinkTOPath = @"/Users/caoguofang/Desktop/新建上层文件夹2";
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
BOOL ifCopy = [fm copyItemAtPath:carrierPListSymLinkPath toPath:carrierPListSymLinkTOPath error:&error];
将一个已存在的文件或者文件夹拷贝到另一个未存在的路径里
打进结果: YES;
2.15(2)
- (BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
此方法和上述方法都是拷贝方法,不同的是参数不同,此方法针对于两个URL之间的操作,可使用下述方法使用
BOOL ifCopy = [fm copyItemAtURL:[NSURL fileURLWithPath:carrierPListSymLinkPath] toURL:[NSURL fileURLWithPath:carrierPListSymLinkTOPath] error:&error];
2.16
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSString *carrierPListSymLinkPath = @"/Users/caoguofang/Desktop/apple.html";
NSString *carrierPListSymLinkTOPath = @"/Users/caoguofang/Desktop/新建上层文件夹/apple.html";
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
BOOL ifMove = [fm moveItemAtPath:carrierPListSymLinkPath toPath:carrierPListSymLinkTOPath error:&error];
将一个文件移动到另一个路径里。注:路径里的文件后缀名要一致,不然会导致文件改变格式并且打不开
打印结果:
2.16(2)
- (BOOL)moveItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
此方法和上述方法都是文件或者文件夹移动方法,不同的是参数不同,此方法针对于两个URL之间的操作,可使用下述方法使用
BOOL ifMove = [fm moveItemAtURL:[NSURL fileURLWithPath:carrierPListSymLinkPath] toURL:[NSURL fileURLWithPath:carrierPListSymLinkTOPath] error:&error];
2.17
- (BOOL)linkItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0))
NSString *carrierPListSymLinkPath = @"/Users/caoguofang/Desktop/hah.rtf";
NSString *carrierPListSymLinkTOPath = @"/Users/caoguofang/Desktop/新建上层文件夹/hahaa.rtf";
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
BOOL ifLink = [fm linkItemAtPath:carrierPListSymLinkPath toPath:carrierPListSymLinkTOPath error:&error];
在指定路径中的项之间创建硬链接。(什么叫硬链接,硬链接和拷贝有啥区别)
打印结果
2.17(2)
- (BOOL)linkItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
此方法和上述方法都是文件或者文件夹创建硬链接方法,不同的是参数不同,此方法针对于两个URL之间的操作,可使用下述方法使用
BOOL ifLink = [fm linkItemAtURL:[NSURL fileURLWithPath:carrierPListSymLinkPath] toURL:[NSURL fileURLWithPath:carrierPListSymLinkTOPath] error:&error];
2.18
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0))
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
BOOL ifLink = [fm removeItemAtPath:@"/Users/caoguofang/Desktop/新建上层文件夹2" error:&error];
删除一个指定路径的文件
打印结果
2.18(2)
此方法和上述方法都是删除文件或者文件夹的方法,不同的是参数不同,此方法针对于两个URL之间的操作,可使用下述方法使用
BOOL ifLink = [fm removeItemAtURL:[NSURL fileURLWithPath:carrierPListSymLinkPath] error:&error];
2.19
- (BOOL)trashItemAtURL:(NSURL *)url resultingItemURL:(NSURL * _Nullable * _Nullable)outResultingURL error:(NSError **)error API_AVAILABLE(macos(10.8), ios(11.0))API_UNAVAILABLE(watchos, tvos);
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *url = [NSURL URLWithStringcreateSymbolicLinkAtPath:@"file:///Users/caoguofang/Documents/DDOtherCompanyInfor.plist"];
NSURL *befoUrl = [NSURL URLWithString:@"file:///Users/caoguofang/.Trash/DDOtherCompanyInfor.plist"];
if (@available(iOS 11.0, *)) {
BOOL trash = [fm trashItemAtURL:befoUrl resultingItemURL:&url error:&error];
} else {
// Fallback on earlier versions
}
/**
将项目移动到废纸篓
@param url 要移动到废纸篓的项目地址
@param outResultingURL 项目移动到废纸篓后的URL地址
@param error 错误信息
@return 操作结果
*/
2.20
- (nullable NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *url = [NSURL URLWithString:@"/Users/caoguofang/Documents/DDOtherCompanyInfor.plist"];
NSDictionary *dic = [fm attributesOfItemAtPath:@"/Users/caoguofang/Documents/DDOtherCompanyInfor.plist" error:&error];
获取某一文件的所有属性
打印结果:
2.21
- (BOOL)setAttributes:(NSDictionary *)attributes ofItemAtPath:(NSString *)path error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSDictionary *setDic =[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate];
BOOL ifSet = [fm setAttributes:setDic ofItemAtPath:@"/Users/caoguofang/Desktop/hah.rtf" error:&error];
更改文件的属性
打印结果:
2.22
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary *)attributes error:(NSError **)error API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *str = @"Users/caoguofang/Desktop/创建文件";
BOOL ifMake = [fileManager createDirectoryAtPath:str withIntermediateDirectories:YES attributes:nil error:nil];
创建指定路径的文件,withIntermediateDirectories这个字段,如果是写的YES ,那即使写的文件上层目录不存在也会重新自动创建一个,如果是NO,如果上层目录不存在,将不会自动创建上层,返回nil
2.23
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
- (BOOL)linkPath:(NSString *)src toPath:(NSString *)dest handler:(nullableid)handler API_DEPRECATED("Not supported", macos(10.0,10.5), ios(2.0,2.0), watchos(2.0,2.0), tvos(9.0,9.0));
- (BOOL)copyPath:(NSString *)src toPath:(NSString *)dest handler:(nullableid)handler API_DEPRECATED("Not supported", macos(10.0,10.5), ios(2.0,2.0), watchos(2.0,2.0), tvos(9.0,9.0));
- (BOOL)movePath:(NSString *)src toPath:(NSString *)dest handler:(nullableid)handler API_DEPRECATED("Not supported", macos(10.0,10.5), ios(2.0,2.0), watchos(2.0,2.0), tvos(9.0,9.0));
- (BOOL)removeFileAtPath:(NSString *)path handler:(nullable id)handler API_DEPRECATED("Not supported", macos(10.0,10.5), ios(2.0,2.0), watchos(2.0,2.0), tvos(9.0,9.0));
#endif
2.24
- (BOOL)fileExistsAtPath:(NSString *)path;
iOS系统中判断文件或者目录是否存在,可以用上面这个API。
2.25
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(nullable BOOL*)isDirectory;
iOS系统中判断文件或者目录是否存在,可以用上面这个API。
第二个参数 isDirectory是个传出参数, 用于返回,是文件还是目录。
BOOL ifDirectory = NO;
BOOL ifExit = [fm fileExistsAtPath:@"/Users/caoguofang/Desktop/" isDirectory:&ifDirectory];
if(ifExit)
{
NSLog(@"%@",ifDirectory ? @"1" : @"0");
}
打印结果
2.26
- (BOOL)isReadableFileAtPath:(NSString *)path;
判断一个路径是否可读
NSFileManager *fm = [NSFileManager defaultManager];
BOOL ifRead = [fm isReadableFileAtPath:@"/Users/caoguofang/Desktop/hahhahahahha.rtf"];
2.27
- (BOOL)isWritableFileAtPath:(NSString *)path;
判断一个路径是否可写
NSFileManager *fm = [NSFileManager defaultManager];
BOOL ifRead = [fm isWritableFileAtPath:@"/Users/caoguofang/Desktop/"];
2.28
- (BOOL)isExecutableFileAtPath:(NSString *)path;
判断一个路径是否允许被操作
NSFileManager *fm = [NSFileManager defaultManager];
BOOL ifExe = [fm isExecutableFileAtPath:@"/Users/caoguofang/Desktop/"];
2.29
- (BOOL)isDeletableFileAtPath:(NSString *)path;
判断一个路径是否允许被删除
NSFileManager *fm = [NSFileManager defaultManager];
BOOL ifDel = [fm isDeletableFileAtPath:@"/Users/caoguofang/Desktop/"];
2.30
- (BOOL)contentsEqualAtPath:(NSString *)path1 andPath:(NSString *)path2;
判断两个文件或者文件夹的内容是否一致
NSFileManager *fm = [NSFileManager defaultManager];
BOOL ifEqua = [fm contentsEqualAtPath:@"/Users/caoguofang/Desktop/未命名文件夹" andPath:@"/Users/caoguofang/Desktop/新建上层文件夹"];
2.31
- (NSString *)displayNameAtPath:(NSString *)path;
NSFileManager *fm = [NSFileManager defaultManager];
NSString *str = [fm displayNameAtPath:@"/Users/caoguofang/Desktop/未命名文件夹"];
获取文件或者文件夹的名字,不能获取后缀名
2.32
- (nullable NSArray *)componentsToDisplayForPath:(NSString *)path;
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *arr = [fm componentsToDisplayForPath:@"/Users/caoguofang/Desktop/未命名文件夹"];
获取文件层级关系,以数组形式返回
打印结果:
3.33
- (nullable NSDirectoryEnumerator *)enumeratorAtPath:(NSString*)path;
NSFileManager *fm = [NSFileManager defaultManager];
NSDirectoryEnumerator *dirEnum;
NSString *path = @"/Users/caoguofang/Desktop/未命名文件夹";
dirEnum = [fm enumeratorAtPath:path];
NSLog(@"1.Contents of %@:",path);
while ((path = [dirEnum nextObject]) != nil)
{
NSLog(@"%@",path);
}
深度遍历文件夹内容
打印结果:
3.34
- (nullable NSDirectoryEnumerator *)enumeratorAtURL:(NSURL *)url includingPropertiesForKeys:(nullable NSArray *)keys options:(NSDirectoryEnumerationOptions)mask errorHandler:(nullable BOOL (^)(NSURL *url, NSError *error))handler API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
NSDirectoryEnumerationOptions options=(NSDirectoryEnumerationSkipsHiddenFiles);
NSArray *keyArray=[NSArray arrayWithObjects:NSURLIsDirectoryKey,nil];
NSString *fileUrl = @"/Users/caoguofang/Desktop/未命名文件夹";
NSURL *url = [NSURL fileURLWithPath:fileUrl];
NSDirectoryEnumerator *dirEnum1=[fm enumeratorAtURL:url includingPropertiesForKeys:keyArray options:options errorHandler:nil];
NSLog(@"1.Contents of %@:",fileUrl);
while ((fileUrl = [dirEnum1 nextObject]) != nil)
{
NSLog(@"%@",fileUrl);
}
深度遍历文件夹里面的文件和文件夹
其里面的两个参数,includingPropertiesForKeys 和 options 可以很好的帮助我们进行很好的设置
includingPropertiesForKeys是一个包含属性的数组,比如:NSURLIsDirectoryKey,这个属性
就可以帮助我们获取文件是否是文件夹
options可以用来设置需要过滤的文件,比如:NSDirectoryEnumerationSkipsHiddenFiles
就可以过滤掉隐藏的文件
includingPropertiesForKeys 属性有好多,这里仅介绍几个:
NSURLNameKey:文件名
NSURLIsDirectoryKey:是否是文件夹
NSURLIsPackageKey:是否是一个包(比如APP)
NSURLIsHiddenKey:是否是隐藏文件
NSURLCreationDateKey:创建日期
options 的属性:
NSDirectoryEnumerationSkipsSubdirectoryDescendants: 浅层的枚举,不会枚举子目录
NSDirectoryEnumerationSkipsPackageDescendants: 不会扫描pakages的内容
NSDirectoryEnumerationSkipsHiddenFile: 不会扫描隐藏文件
3.35
- (nullable NSArray *)subpathsAtPath:(NSString *)path;
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *arr = [fm subpathsAtPath:@"/Users/caoguofang/Desktop/未命名文件夹"];
此方法不推荐,推荐用“subpathsOfDirectoryAtPath”来代替
3.36