前言

最近在学习数据持久化相关的内容,文件作为 iOS 客户端开发中一种常见的数据保存方式,自然也是应该学习的内容,本文就来简单介绍文件相关的一些知识。

文章目录

  • 前言
  • 1. 文件基础
    • 沙盒路径获取
    • NSString 路径操作
    • NSData 类型转换
  • 2. NSFileManager 文件操作
    • 2.1 创建文件和目录
    • 2.2 文件剪切和复制
    • 2.3 文件删除
  • 3. NSFileHandle 文件读写
    • 3.1 常用方法
  • 参考资料

1. 文件基础

在 iOS 系统中,所有非系统应用都经过了沙盒化,每个应用都拥有自己的沙盒(Sandbox)用于存储本应用的文件数据,不同应用沙盒之间是相互独立的,而且本应用不能访问其他应用的沙盒。

沙盒机制保证了 iOS 应用的安全性,能有效防止 App 收集和篡改其他 App 存储的信息。如果第三方 App 需要访问除自身以外的其他信息,只能通过 iOS 系统明确提供的服务来实现。

应用沙盒的结构如下图所示:

下面简单介绍一下沙盒各个路径的内容:

  • /Document 目录:用于存放程序中的文件数据,应用程序在运行时生成一些需要长久保存的数据,如游戏进程存档,为编辑完的文档等。iTunes 、iCloud 对应用信息备份时,会备份这个目录下的数据,因此会在此目录保存相对重要的数据。
  • /Library 包含下面两个子目录
    • /Library/Caches 目录 :恰如其名,该目录用于存放缓存文件,从网络上下载的文件或数据(如:音乐缓存、图片缓存等)都会保存在该目录下。该目录下的文件不会在应用退出时手动删除,需要程序员手动清除该目录下的数据。iTunes 、iCloud 不会对该目录下的数据进行备份。
    • /Library/Preferences 目录:存放的是基于 NSUserDefaults 的设置数据,文件格式为 .plist。设置应用的一些功能会在该目录中查找相应设置的信息,iTunes、iCloud备份时会备份此目录下的数据。该目录由系统自动管理,通常用来储存一些基本的应用配置信息。
  • /Temp 目录:存放应用运行时产生的一些临时数据和文件,当应用程序退出、系统磁盘空间不足、手机重启时,都会自动清除该目录的数据。无需程序员手动清除该目录中的数据,iTunes、iCloud备份时不会备份此目录。

沙盒路径获取

我们可以通过下面的方法,获取到上面提及到的沙盒目录。

// 获取沙盒根目录
NSString *homeDir = NSHomeDirectory();// 获取 /Document 目录
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];// 获取 /Library 目录
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory , NSUserDomainMask , YES) lastObject];// 获取 /Library/Caches 目录
NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];// 获取 /Temp 目录
NSString *tmpDir = NSTemporaryDirectory();

NSString 路径操作

要想对文件进行操作,必然会涉及到文件路径的处理。在 NSString 中,也给我们提供了路径操作相关的 API。

/// 路径分解,例如 /Users/Apple/file.txt 会得到 "/", "Users", "Apple", "file.txt"
- (NSArray *)pathComponents;// 获取路径的最后部分,例如 /Users/Apple/file.txt 会得到 "file.txt"
- (NSString *)lastPathComponent;// 在路径末尾添加路径,会自动处理 "/"
- (NSString *)stringByAppendingPathConmponent:(NSString *)str;// 删除路径的最后部分,例如 /Users/Apple/file.txt 会得到 /Users/Apple/
- (NSString *)stringByDeletingLastPathCpmponent;// 为路径添加拓展名,传参的时候不用加 "."
- (NSString *)stringByAppendingPathExtension:(NSString *)str;// 删除路径末尾的拓展名
- (NSString *)stringByDeletingPathExtension;

NSData 类型转换

我们读取文件时,通常获取到的都是 NSData 类型的对象,下面是 NSData 到其他常用类型的相互转换方法。

// NSString 和 NSData 互转
NSString *str = @"Veggie";
NSData *strToData = [str dataUsingEncoding:NSUTF8StringEncoding];
NSString *dataToStr = [[NSString alloc] initWithData:strToData encoding:NSUTF8StringEncoding];// int 和 NSData 互转
int i = 1024;
NSData *intToData = [NSData dataWithBytes:&i length:sizeof(i)];
int dataToInt;
[intToData getBytes:&dataToInt length:sizeof(dataToInt)];// UIImage 和 NSData 互转
UIImage *image = [UIImage imageNamed:@"test"];
NSData *imageToData = UIImagePNGRepresentation(image);
UIImage *dataToImage = [UIImage imageWithData:imageToData];// NSArray 和 NSData 互转
NSArray *arr = @[@"1", @"2", @"3"];
NSData *arrToData = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:nil];
NSArray *dataToArr = [NSJSONSerialization JSONObjectWithData:arrToData options:NSJSONReadingMutableContainers error:nil];// NSDictionary 和 NSData 互转
NSDictionary *dic = @{@"user_name" : @"veggie",@"user_age" : @"18"
};
NSData *dicToData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSArray *dataToDic = [NSJSONSerialization JSONObjectWithData:dicToData options:NSJSONReadingMutableContainers error:nil];

2. NSFileManager 文件操作

我们想对沙盒中的目录和文件进行操作时,可以用上系统为我们提供的 NSFileManager 文件管理类。下面就通过封装方法的形式,简单介绍 NSFileManager 的使用。

2.1 创建文件和目录

创建目录

- (BOOL)createDir:(NSString *)path {NSAssert(path > 0, @"%s: The length of path should be greater than 0.", __FUNCTION__);NSFileManager *fileManager = [NSFileManager defaultManager];BOOL isSuccess = YES;// 判断目录是否已经存在if (![fileManager fileExistsAtPath:path]) {// 创建文件目录NSError *error = nil;isSuccess = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];if (error) {NSLog(@"Create directory failed: %@",[error localizedDescription]);}}return isSuccess;
}

创建文件,在创建之前需要确定文件的存储路径是存在的,如果不存在,则现在执行目录创建操作。

- (BOOL)createFile:(NSString *)filePath {NSAssert(filePath > 0, @"%s: The length of filePath should be greater than 0.", __FUNCTION__);NSFileManager *fileManager = [NSFileManager defaultManager];// 提取出文件存放的目录NSString *dir = [filePath stringByDeletingLastPathComponent];// 判断目录是否已经存在if (![fileManager fileExistsAtPath:dir]) {// 如果还没有存在,则需要新建NSError *error = nil;[fileManager createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:&error];if (error) {NSLog(@"Create directory failed: %@",[error localizedDescription]);return NO;}}// 创建文件return [fileManager createFileAtPath:filePath contents:nil attributes:nil];
}

2.2 文件剪切和复制

这里以一个简单的任务来举例,我们需要将 /Documents/from 目录下的所有文件(文件名格式有规律)移动到 /Documents/to 目录下,其目录内容如下图所示。

我们使用 NSFileManager 来实现,代码如下:

NSString *fromPath = @"/Users/user_name/Documents/from";
NSString *toPath = @"/Users/user_name/Documents/to";NSFileManager *fileManager = [NSFileManager defaultManager];for (int i = 0; i < 100; i++) {NSString *fileName = [NSString stringWithFormat:@"veggie-%d.txt", i];// 注意:在 from 和 to 路径上都要拼上文件名NSString *fileFromPath = [fromPath stringByAppendingPathComponent:fileName];NSString *fileToPath = [toPath stringByAppendingPathComponent:fileName];// 执行移动操作NSError *error = nil;BOOL isSuccess = [fileManager moveItemAtPath:fileFromPath toPath:fileToPath error:&error];if (isSuccess) {NSLog(@"moveFile Success!");} else {NSLog(@"moveFile Field:%@",[error localizedDescription]);}
}

复制操作和上面的代码非常详细,用到的是下面这个 API,需要特别注意的是,参数中 srcPathdstPath 路径都要拼上文件名

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

2.3 文件删除

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

3. NSFileHandle 文件读写

NSFileHandle 主要用于对文件进行 I/O 操作,它的使用通常包括以下几个步骤:

  • 打开文件,获取文件对应的 NSFileHandle 对象
  • 对该文件执行 I/O 操作(读取、写入、插入)
  • 关闭文件

3.1 常用方法

// 打开一个文件,准备读取
+ (nullable instancetype)fileHandleForReadingAtPath:(NSString *)path;
// 打开一个文件,准备写入(会发生覆盖)
+ (nullable instancetype)fileHandleForWritingAtPath:(NSString *)path;
// 打开一个文件,准备插入内容
+ (nullable instancetype)fileHandleForUpdatingAtPath:(NSString *)path;// 返回可用的数据
- (NSData *)availableData;
// 从当前的节点读取到文件的末尾
- (NSData *)readDataToEndOfFile;
// 从当前节点开始读取指定的长度数据
- (NSData *)readDataOfLength:(NSUInteger)length;
// 写入数据
- (void)writeData:(NSData *)data;
// 获取当前文件的偏移量
- (unsigned long long)offsetInFile;
// 跳到指定文件的偏移量
- (void)seekToFileOffset:(unsigned long long)offset;
// 跳到文件末尾
- (unsigned long long)seekToEndOfFile;
// 将文件的长度设为offset字节
- (void)truncateFileAtOffset:(unsigned long long)offset;
// 关闭文件
- (void)closeFile;

参考资料

  • File System Programming Guide | Apple Developer Documentation
  • NSFileManager | Apple Developer Documentation
  • NSString | Apple Developer Documentation
  • NSData | Apple Developer Documentation

好像又写了一篇没什么用的文章,希望后面在开发中用上了相关技术,可以再次回到这里更新自己的想法。

iOS - 沙盒文件操作指南相关推荐

  1. iOS沙盒文件夹及获取路劲方法

    iPhone沙盒中有四个文件夹,分别是:documents.tmp.app.library. 1.Documents :用户生成的文档或数据,或者应用不能重新新创建的数据,存储在/Documents目 ...

  2. iOS学习之iOS沙盒(sandbox)机制和文件操作(二)

    接上篇 iOS学习之iOS沙盒(sandbox)机制和文件操作(一) 我们看看如何获取应用程序沙盒目录.包括真机的沙盒的目录. 1.获取程序的Home目录 [cpp] view plaincopy N ...

  3. iOS学习之iOS沙盒(sandbox)机制和文件操作复习

    1.iOS沙盒机制 iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. ...

  4. IOS 沙盒(sandbox)机制和文件操作

    1.IOS沙盒机制( 沙盒(sandbox)机制) IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声 ...

  5. iOS学习之iOS沙盒(sandbox)机制和文件操作(一)

    1.iOS沙盒机制 iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. ...

  6. iOS沙盒(sandbox)机制和文件操作

    本文转载自http://blog.csdn.net/totogo2010/article/details/7671144,感谢作者 1.iOS沙盒机制 iOS应用程序只能在为该改程序创建的文件系统中读 ...

  7. ios沙箱软件_ios真机和模拟器沙盒文件(一)

    版本记录 版本号 时间 V1.0 2017.06.11 前言 我们有时候需要在沙盒中存储东西,所以总有需求就是查看沙盒文件里面存储的文件,这就需要我们查看沙盒文件,沙盒文件包括真机的沙盒文件和模拟器的 ...

  8. IOS沙盒Files目录说明和常用操作

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

  9. iOS学习7:iOS沙盒(sandBox)机制(一)之获取沙盒路径及目录说明(转)

    转:http://my.oschina.net/joanfen/blog/151145 一.iOS沙盒机制 iOS的应用只能访问为该应用创建的区域,不可访问其他区域,应用的其他非代码文件都存在此目录下 ...

最新文章

  1. consul-template + nginx部署高可用负载均衡
  2. OPA start up and wait for
  3. 昆明理工计算机科学,昆明理工大学的计算机
  4. LeetCode 1980. 找出不同的二进制字符串
  5. python变量名称跟着循环_python在循环中存储每次迭代使用不同名称的输入变量
  6. 那朵美丽的格桑花,你是否依然绽放?
  7. 为什么现代系统需要一个新的编程模型?
  8. SIP消息头域的说明
  9. caption里面能不能加字体颜色的设置_短视频快速加SRT字幕这事 有几条Pr避坑指南请查收...
  10. 概率论由相关性求数学期望和方差的公式_2020.3.30 | 考研数学—概率论与数理统计:各章节考试重点...
  11. android++日历示例,Android开发之日历CalendarView用法示例
  12. XCTF-2020CyBRICS部分逆向
  13. DirectX 9.0 (5) 点光源
  14. 工程伦理计算机论文,工程实践中的伦理问题研究
  15. 3分钟教你如何在Word里快速制作单斜线和多斜线表头
  16. Unity特效基础:粒子效果面板
  17. python 制作正态分布图,画出拒绝域
  18. 枣庄高新技术企业认定优惠政策,同邦科技分享
  19. 模拟电路1(二极管半导体知识)
  20. 无心剑七绝147首[1994年~2021年]

热门文章

  1. windows结束线程的三种方式
  2. Ubuntu报错记录(Could not get lock /var/lib/dpkg/lock-frontend问题的解决方法)
  3. 无线网络渗透测试-使用Wifite破解无线网络
  4. 反编译apk文件教程(查看java代码篇)
  5. 【python】简单记录
  6. 3、(小数类型)FLOAT、DOUBLE、DECIMAL
  7. 第十二届蓝桥杯省赛第二场C++B组真题 【未完结】
  8. C语言之字符串处理函数
  9. php 代码线程,php实现多线程代码
  10. linux中的c 环境变量,Linux C 参考手册 之 环境变量篇