ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

iOS沙盒操作 NSFileManager

2021-06-01 18:56:49  阅读:184  来源: 互联网

标签:toPath return error iOS NSString BOOL path NSFileManager 沙盒


沙盒机制

每一个iOS应用程序都会为自己创建一个文件系统目录,这个独立、封闭、安全的空间叫做沙盒。沙盒就是一种安全体系,它规定了应用程序只能在自己的文件系统目录内访问文件,不可以访问其他应用沙盒内的内容。所有的非代码文件都保存在这个地方。

沙盒根目录结构:Documents、Library、temp

 

image

Documents

保存应用运行时生成的需要持久化的数据,iTunes备份和恢复的时候会包括此目录,所以苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下。

Library

  • Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出后删除 。一般存放体积比较大,不是特别重要的资源。
  • Preferences:保存APP的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息,iTunes会自动备份该目录。注意:通过NSUserDefaults类来读取和设置。

tmp

保存应用运行时所需的临时数据,这个可以放一些当APP退出后不再需要的文件。应用没有运行时,系统也有可能会清除该目录下的文件,iTunes不会同步该目录。iPhone重启时,该目录下的文件会被删除。

如何查看该目录?

XCode->Window->Devices->真机->Installed Apps->应用->ShowContainer

image.png

也可以点击DownloadContainer下载该沙盒文件查看内容

image.png

获取相关目录

 

// 获取Document目录
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

// 获取Library目录
NSString *LibraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];

// 获取Caches目录
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

// 获取Preferences目录 通常情况下,Preferences有系统维护,所以我们很少去操作它。
NSString *preferPath = [LibraryPath stringByAppendingPathComponent:@"Preferences"];

// 获取tmp目录
NSString *tmpPath = NSTemporaryDirectory();


[toc]
相关文件操作
--

  • 创建文件夹

 

+(BOOL)creatDir:(NSString *)path{
    if (path.length==0) {
        return NO;
    }
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isSuccess = YES;
    BOOL isExist = [fileManager fileExistsAtPath:path];
    if (isExist==NO) {
        NSError *error;
        if (![fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) {
            isSuccess = NO;
            NSLog(@"creat Directory Failed:%@",[error localizedDescription]);
        }
    }
    return isSuccess;
}

  • 创建文件

 

+(BOOL)creatFile:(NSString*)filePath{
    if (filePath.length==0) {
        return NO;
    }
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:filePath]) {
        return YES;
    }
    NSError *error;
    NSString *dirPath = [filePath stringByDeletingLastPathComponent];
    BOOL isSuccess = [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error];
    if (error) {
        NSLog(@"creat File Failed:%@",[error localizedDescription]);
    }
    if (!isSuccess) {
        return isSuccess;
    }
    isSuccess = [fileManager createFileAtPath:filePath contents:nil attributes:nil];
    return isSuccess;
}

  • 写数据

 

+(BOOL)writeToFile:(NSString*)filePath contents:(NSData *)data{
    if (filePath.length==0) {
        return NO;
    }
    BOOL result = [self creatFile:filePath];
    if (result) {
        if ([data writeToFile:filePath atomically:YES]) {
            NSLog(@"write Success");
        }else{
            NSLog(@"write Failed");
        }
    }
    else{
        NSLog(@"write Failed");
    }
    return result;
}

  • 追加写数据

 

+(BOOL)appendData:(NSData*)data withPath:(NSString *)filePath{
    if (filePath.length==0) {
        return NO;
    }
    BOOL result = [self creatFile:filePath];
    if (result) {
        NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:filePath];
        [handle seekToEndOfFile];
        [handle writeData:data];
        [handle synchronizeFile];
        [handle closeFile];
    }
    else{
        NSLog(@"appendData Failed");
    }
    return result;
}

  • 读文件数据

 

+(NSData*)readFileData:(NSString *)path{
    NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:path];
    NSData *fileData = [handle readDataToEndOfFile];
    [handle closeFile];
    return fileData;
}

  • 获取文件夹下所有的文件列表

 

+(NSArray*)getFileList:(NSString*)path{
    if (path.length==0) {
        return nil;
    }
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *fileList = [fileManager contentsOfDirectoryAtPath:path error:&error];
    if (error) {
        NSLog(@"getFileList Failed:%@",[error localizedDescription]);
    }
    return fileList;
}

  • 获取文件夹下所有文件(深度遍历)

 

+(NSArray*)getAllFileList:(NSString*)path{
    if (path.length==0) {
        return nil;
    }
    NSArray *fileArray = [self getFileList:path];
    NSMutableArray *fileArrayNew = [NSMutableArray array];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    for (NSString *aPath in fileArray) {
        NSString * fullPath = [path stringByAppendingPathComponent:aPath];
        BOOL isDir = NO;
        if ([fileManager fileExistsAtPath:fullPath isDirectory:&isDir]) {
            if (isDir) {
                [fileArrayNew addObjectsFromArray:[self getAllFileList:fullPath]];
            }else{
                [fileArrayNew addObject:fullPath];
            }
        }
    }
    return fileArrayNew;
}

  • 移动文件

 

+(BOOL)moveFile:(NSString *)fromPath toPath:(NSString *)toPath toPathIsDir:(BOOL)dir{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:fromPath]) {
        NSLog(@"Error: fromPath Not Exist");
        return NO;
    }
    BOOL isDir = NO;
    BOOL isExist = [fileManager fileExistsAtPath:toPath isDirectory:&isDir];
    if (isExist) {
        if (isDir) {
            if ([self creatDir:toPath]) {
                NSString *fileName = fromPath.lastPathComponent;
                toPath = [toPath stringByAppendingPathComponent:fileName];
                return [self moveItemAtPath:fromPath toPath:toPath];
            }
        }else{
            [self removeFile:toPath];
            return [self moveItemAtPath:fromPath toPath:toPath];
        }
    }
    else{
        if (dir) {
            if ([self creatDir:toPath]) {
                NSString *fileName = fromPath.lastPathComponent;
                toPath = [toPath stringByAppendingPathComponent:fileName];
                return [self moveItemAtPath:fromPath toPath:toPath];
            }
        }else{
            return [self moveItemAtPath:fromPath toPath:toPath];
        }
    }
    return NO;
}
+(BOOL)moveItemAtPath:(NSString*)fromPath toPath:(NSString*)toPath{
    BOOL result = NO;
    NSError * error = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    result = [fileManager moveItemAtPath:fromPath toPath:toPath error:&error];
    if (error){
        NSLog(@"moveFile Fileid:%@",[error localizedDescription]);
    }
    return result;
}

  • 删除文件

 

+(BOOL)removeFile:(NSString*)filePath{
    BOOL isSuccess = NO;
    NSError *error;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    isSuccess = [fileManager removeItemAtPath:filePath error:&error];
    if (error) {
        NSLog(@"removeFile Field:%@",[error localizedDescription]);
    }else{
        NSLog(@"removeFile Success");
    }
    return isSuccess;
}

  • 删除文件夹

 

+(BOOL)removeDir:(NSString*)path{
    return [self removeFile:path];
}

  • 删除某些后缀的文件

 

+(void)removeFileSuffixList:(NSArray<NSString*>*)suffixList filePath:(NSString*)path deep:(BOOL)deep{
    NSArray *fileArray = nil;
    if (deep) {  // 是否深度遍历
        fileArray = [self getAllFileList:path];
    }else{
        fileArray = [self getFileList:path];
        NSMutableArray *fileArrayTmp = [NSMutableArray array];
        for (NSString *fileName in fileArray) {
            NSString* allPath = [path stringByAppendingPathComponent:fileName];
            [fileArrayTmp addObject:allPath];
        }
        fileArray = fileArrayTmp;
    }
    for (NSString *aPath in fileArray) {
        for (NSString* suffix in suffixList) {
            if ([aPath hasSuffix:suffix]) {
                [self removeFile:aPath];
            }
        }
    }
}

  • 获取文件大小

 

+(long long)getFileSize:(NSString*)path{
    unsigned long long fileLength = 0;
    NSNumber *fileSize;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:path error:nil];
    if ((fileSize = [fileAttributes objectForKey:NSFileSize])) {
        fileLength = [fileSize unsignedLongLongValue]; //单位是 B
    }
    return fileLength;
}

  • 获取文件的信息(包含了上面文件大小)

 

+(NSDictionary*)getFileInfo:(NSString*)path{
    NSError *error;
    NSDictionary *reslut =  [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error];
    if (error) {
        NSLog(@"getFileInfo Failed:%@",[error localizedDescription]);
    }
    return reslut;
}


[toc]

NSFileManager和NSFileHandle

1、NSFileManager(文件管理对象)

主要是对文件进行的操作(创建/删除/改名等)以及文件信息的获取。

方法 说明
@property (class, readonly, strong) NSFileManager *defaultManager 创建文件管理对象
-(BOOL)fileExistsAtPath:(NSString *)path isDirectory:(nullable BOOL *)isDirectory 判断某个路径是否存在,isDirectory是一个指针,表示该路径是否是目录
-(BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(nullable NSDictionary<NSString *, id> *)attributes error:(NSError **)error 创建一个目录
-(BOOL)createFileAtPath:(NSString *)path contents:(nullable NSData *)data attributes:(nullable NSDictionary<NSString *, id> *)attr 创建一个文件,可顺便写入data
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile NSData类型的写入数据,读数据请自行查阅
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error NSString、NSArray、NSDictionary的写入数据,读数据请自行查阅
-(nullable NSArray<NSString *> *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error 获取当前文件夹下的文件/目录
-(BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error 移动文件,可用来重命名
-(BOOL)copyItemAtURL:(NSURL *)srcURL toURL:(NSURL *)dstURL error:(NSError **)error 复制文件
-(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error 删除文件
-(nullable NSDictionary<NSFileAttributeKey, id> *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error 获取文件信息(文件大小、修改时间、所有者等)

</b>

2、NSFileHandle(文件连接器)

主要是对文件内容进行读取和写入操作

方法 说明
+(nullable instancetype)fileHandleForWritingAtPath:(NSString *)path 写的方式打开文件
+(nullable instancetype)fileHandleForReadingAtPath:(NSString *)path 读的方式打开文件
-(unsigned long long)seekToEndOfFile 跳到文件末尾
-(void)seekToFileOffset:(unsigned long long)offset 跳到指定偏移位置
-(void)truncateFileAtOffset:(unsigned long long)offset 将文件的长度设为offset字节
-(NSData *)readDataToEndOfFile 从当前字节读取到文件到末尾数据
-(NSData *)readDataOfLength:(NSUInteger)length 从当前字节读取到指定长度数据
-(void)synchronizeFile 同步文件,通常用在写入数据后
-(void)closeFile 关闭文件

对象等复杂类型的读写操作

上述数据操作,支持的类型仅仅是NSString、NSArray、NSDictionary、NSData类型,这些都数据类型都支持了NSCoding协议,可以进行数据持久化。如果我们想存储如UIImage、自定义的对象等类型,我们都需要将其转换为NSData类型,如转换UIImage为NSData使用UIImagePNGRepresentation(image)等方法,而自定义对象类型则需要进行归档、反归档来进行存取操作

存:

对象->归档->NSData->文件写入

取:

文件读取->NSData->反归档->对象

自定义对象需要遵守NSCoding协议并实现

 

- (void)encodeWithCoder:(NSCoder *)aCoder;  //序列化 
- (id)initWithCoder:(NSCoder *)aDecoder;    //反序列化

两个方法



作者:程序圆圆
链接:https://www.jianshu.com/p/52aa11712ba0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:toPath,return,error,iOS,NSString,BOOL,path,NSFileManager,沙盒
来源: https://blog.51cto.com/u_4955660/2842828

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有