File System Basics
文件系统负责处理数据文件、应用程序以及与操作系统相关的文件的持久性保存。
在iOS 10.3版本之后,APFS(Apple File System)替代了原有的HFS+成为了默认的文件系统。
所有连接到设备上的磁盘,无论是物理意义上的还是通过网络连接的,都为文件系统贡献自己的存储空间,因为文件📃的数量可能会相当多,所以文件系统使用「目录」来创建了一种文件的层次结构。
文件系统有两个基本的原则:
- 应用程序无法向自己权限之外的文件进行「写」的操作。
- 在应用程序内部,不同的文件被期望放置在正确的位置。
iOS文件系统面向自己运行的应用程序。为了保持系统简单,iOS设备的用户无法直接访问文件系统,应用程序应遵循此惯例。
出于安全的考虑,iOS与文件系统的交互被限制在了自己的「沙盒」目录中。
如上图所示,应用程序通常被禁止访问(或创建目录)自己的文件目录之外的文件,如上图所示。但访问「联系人」或「音乐」是一个例外。
Bundle是文件系统中的一个目录,它将可执行代码、图像、声音、NIB文件、私有框架和库、插件、可加载包或任何其他类型的代码或资源集中在一个位置。
Directory | Discription |
---|---|
Name.app | 应用程序捆绑包,包含程序运行所需的全部必要资源,签名机制防篡改,无法写入。此目录的内容不会由iTunes或iCloud备份。 |
Documents/ | 该目录应该只包含您可能希望向用户公开的文件,如绘画软件的画稿。该目录的内容由iTunes和iCloud备份。 |
Documents/Inbox | 外部实体要求应用程序打开的文件。可以读取和删除此目录中的文件,但不能创建新文件或写入现有文件。此目录的内容由iTunes和iCloud备份。 |
Library/ | 使用Library保存不想暴露给用户的任何文件。该目录通常包括 Application Support 和 Caches 子目录;但也可以创建自定义子目录。库目录的内容(缓存子目录除外)由iTunes和iCloud备份。 |
tmp/ | 使用此目录保存不需要在应用程序启动之间保留的临时文件。当应用程序不运行时,系统可能会清除该目录。此目录的内容不会由iTunes或iCloud备份。 |
将文件放置在正确的位置
为了防止备份到iCloud / iTunes的时间过长,需要将文件放置在合适的位置上。
-
将应用程序创建的支持文件放在
Library/Application support/
目录中。一般来说这些文件是需要向用户隐藏的,比如data files
,configuration files
,templates
。 -
Documents/
和Application Support/
是默认备份的,可以在调用-[NSURL setResourceValue:forKey:error:]
方法时传入NSURLIsExcludedFromBackupKey
键来指定不需要备份的文件。原则上所有可以被重新创建的 / 下载的文件都需要被排除。 -
缓存数据保存在
Library/Caches/
中,缓存数据保存时间要长于tmp/
,缓存数据并不影响程序正常运行,但可以提高运行的性能。一些需要网络上下载的内容可以保存在这里。
iCloud
iCloud提供了另一种结构化的文件存储方式:
- 应用程序具有用于存储其本机文件的主iCloud容器目录。还可以访问其应用程序权利中列出的辅助iCloud容器目录。
- iCloud中的文件备份成「documents」和「data」两部分,所有「documents」中的数据可以通过UI暴露给用户。
任何不能向用户暴露的文件都不应该放在「documents」中,而是应该在「container」中新建一个子文件夹。
访问文件或目录
访问文件或目录有两种方式:URL or String-Based Path
不同文件的访问方式:Resource Programming Guide. & String Programming Guide. & Event-Driven XML Programming Guide. & Archives and Serializations Programming Guide. & Bundle Programming Guide
官方推荐使用URLs来访问文件。
Path-based URL: file://localhost/Users/steve/Documents/MyFile.txt
File reference URL: file:///.file/id=6571367.2773272/
String-based path: /Users/steve/Documents/MyFile.txt
可以通过NSURL类来创建URL对象,需要的时候也可以将其转换为reference URL。
NSURL
的AboutteString
方法可以将NSURL
对象转换成NSString
对象
必须先创建指向不存在的文件或目录的路径,然后才能在磁盘上创建它。
1 |
|
如果要访问捆绑包内的文件,首先需要在项目的Build Phase
中的Copy Bundle Resources
中手动添加资源,然后通过上面👆这行代码访问。
可以使用FileManager
的单例default
的urls
方法来创建一个特定位置的URL:
1 |
|
这段代码我现在的理解是在某个域中搜索某个位置,返回一个该位置的url,举个栗子🌰,比方说上面这段代码的输出为:
1 |
|
遍历目录:
深搜索🔍:
1 |
|
浅搜索🔍:
1 |
|
看到这里,总之就是,基本上所有跟文件有关系的操作,都找FileManager.default
就好了,包括查找,创建,移动,复制,删除,等等,FileManager.default
还有一个FileManagerDelegate?
类型的属性delegate,里面包括了一些对移动、复制等操作的响应时间,默认都是optional类型的方法。
‼️一个补充知识:
1 |
|
一些常用方法:
最后列举几个比较常见的操作吧:
1 |
|
线程安全
由于文件系统由所有正在运行的进程共享,因此当两个进程(或同一进程中的两个线程)尝试同时对同一文件执行操作时,可能会出现问题。
文件协调器(File coordinator)的工作是每当他们关心的文件被另一个进程或线程操作时通知相关方。
具体的以后再看吧,官方文档全是OC代码,看不懂。
TODO:
-
#### iCloud File Management
-
#### Managing Files and Directories
-
#### Techniques for Reading and Writing Files Without File Coordinators
-
#### Using FileWrappers as File Containers