A file system handles the persistent storage of data files, apps, and the files associated with the operating system itself. Therefore, the file system is one of the fundamental resources used by all processes.
- A 文件系统处理数据文件,应用程序以及与操作系统本身相关的文件的持久存储。 因此,文件系统是所有进程使用的基本资源之一。
APFS is the default file system in macOS, iOS, watchOS, and tvOS. APFS replaces HFS+ as the default file system for iOS 10.3 and later, and macOS High Sierra and later. macOS additionally supports a variety of other formats, as described in Supported File Systems.
- APFS是macOS,iOS,watchOS和tvOS中的默认文件系统。 APFS将HFS +替换为iOS 10.3及更高版本以及macOS High Sierra及更高版本的默认文件系统。 macOS还支持各种其他格式,如支持的文件系统中所述。
Regardless of the underlying format, all of the disks attached to the device—whether they are physically plugged in or are connected indirectly through the network—contribute space to create a single collection of files. Because the number of files can easily be many millions,the file system uses directories to create a hierarchical organization.
Although the basic directory structures are similar for iOS and macOS, there are differences in the way each system organizes apps and user data.
- 无论基础格式如何,连接到设备的所有磁盘 - 无论是物理插入还是通过网络间接连接 - 都会创建单个文件集合。 由于文件数量很容易达到数百万,
因此文件系统使用目录来创建分层组织
。 虽然iOS和macOS的基本目录结构相似,但每个系统组织应用程序和用户数据的方式各不相同。
Before you begin writing code that interacts with the file system, you should first understand a little about the organization of file system and the rules that apply to your code. Aside from the basic tenet that you cannot write files to directories for which you do not have appropriate security privileges, apps are also expected to be good citizens and put files in appropriate places. Precisely where you put files depends on the platform, but the overarching goal is to make sure that the user’s files remain easily discoverable and that the files your code uses internally are kept out of the user’s way.
- 在开始编写与文件系统交互的代码之前,您应该先了解一下文件系统的组织以及适用于您的代码的规则。 除了您无法将文件写入您没有适当安全权限的目录的基本原则之外,应用程序也应该是好公民并将文件放在适当的位置。 准确放置文件的位置取决于平台,但最重要的目标是确保用户的文件易于发现,并且代码内部使用的文件不受用户限制。
About the iOS File System
- 关于iOS文件系统
The iOS file system is geared toward apps running on their own. To keep the system simple, users of iOS devices do not have direct access to the file system and apps are expected to follow this convention.
- iOS文件系统适用于自行运行的应用程序。 为了保持系统简单,iOS设备的用户无法直接访问文件系统,并且应用程序应遵循此约定。
iOS Standard Directories: Where Files Reside
- iOS标准目录:文件驻留的位置
For security purposes, an iOS app’s interactions with the file system are limited to the directories inside the app’s sandbox directory. During installation of a new app, the installer creates a number of container directories for the app inside the sandbox directory. Each container directory has a specific role. The bundle container directory holds the app’s bundle, whereas the data container directory holds data for both the app and the user. The data container directory is further divided into a number of subdirectories that the app can use to sort and organize its data. The app may also request access to additional container directories—for example, the iCloud container—at runtime. - 出于安全考虑,iOS应用程序与文件系统的交互仅限于应用程序沙盒中的目录。 在安装新应用程序期间,安装程序会在沙盒目录中为应用程序创建许多容器目录。 每个容器目录都有一个特定的角色。 包容器目录包含应用程序包,而数据容器目录包含应用程序和用户的数据。 数据容器目录进一步划分为许多子目录,应用程序可以使用这些子目录对数据进行排序和组织。 应用程序还可以在运行时请求访问其他容器目录(例如,iCloud容器)。
These container directories constitute the app’s primary view of the file system. Figure 1-1 shows a representation of the sandbox directory for an app.
- 这些容器目录构成了应用程序的文件系统主视图。 图1-1显示了应用程序的沙箱目录的表示。
在自己的沙箱目录中运行的iOS应用程序
An app is generally prohibited from accessing or creating files outside its container directories. One exception to this rule is when an app uses public system interfaces to access things such as the user’s contacts or music. In those cases, the system frameworks use helper apps to handle any file-related operations needed to read from or modify the appropriate data stores.
- 通常禁止应用程序访问或创建容器目录之外的文件。 此规则的一个例外是当应用程序使用公共系统接口访问用户的联系人或音乐等内容时。 在这些情况下,系统框架使用帮助应用程序来处理读取或修改适当数据存储所需的任何与文件相关的操作。
Table 1-1 lists some of the more important subdirectories inside the sandbox directory and describes their intended usage. This table also describes any additional access restrictions for each subdirectory and points out whether the directory’s contents are backed up by iTunes and iCloud.
- 表1-1列出了sandbox目录中一些更重要的子目录,并描述了它们的预期用法。 此表还描述了每个子目录的任何其他访问限制,并指出目录的内容是否由iTunes和iCloud备份。
Table 1-1 Commonly used directories of an iOS app
- 常用的iOS应用程序目录
Directory1 :AppName.app
Description: This is the app’s bundle. This directory contains the app and all of its resources.
- 这是应用程序的捆绑包。 该目录包含应用程序及其所有资源。
You cannot write to this directory. To prevent tampering, the bundle directory is signed at installation time. Writing to this directory changes the signature and prevents your app from launching. You can, however, gain read-only access to any resources stored in the apps bundle. For more information, see the Resource Programming Guide
- 您无法写入此目录。 为防止篡改,bundle目录在安装时签名。 写入此目录会更改签名并阻止您的应用启动。 但是,您可以获得对应用程序包中存储的任何资源的只读访问权限。 有关更多信息,请参阅“资源编程指南”
The contents of this directory are not backed up by iTunes or iCloud. However, iTunes does perform an initial sync of any apps purchased from the App Store.
- iTunes或iCloud不会备份此目录的内容。 但是,iTunes确实执行从App Store购买的任何应用程序的初始同步。
Directory2 : Documents/
Description: Use this directory to store user-generated content. The contents of this directory can be made available to the user through file sharing; therefore, his directory should only contain files that you may wish to expose to the user.
The contents of this directory are backed up by iTunes and iCloud.
- 使用此目录存储用户生成的内容。 该目录的内容可以通过文件共享提供给用户; 因此,他的目录应该只包含您可能希望向用户公开的文件。
该目录的内容由iTunes和iCloud备份。
Directory3 : Documents/Inbox
Description: Use this directory to access files that your app was asked to open by outside entities. Specifically, the Mail program places email attachments associated with your app in this directory. Document interaction controllers may also place files in it.
- 使用此目录可以访问外部实体要求您打开应用程序的文件。 具体来说,Mail程序将与您的应用程序关联的电子邮件附件放在此目录中。 文档交互控制器也可以在其中放置文件。
Your app can read and delete files in this directory but cannot create new files or write to existing files. If the user tries to edit a file in this directory, your app must silently move it out of the directory before making any changes.
The contents of this directory are backed up by iTunes and iCloud.
- 您的应用可以读取和删除此目录中的文件,但无法创建新文件或写入现有文件。 如果用户尝试编辑此目录中的文件,则在进行任何更改之前,您的应用必须以静默方式将其移出目录。
该目录的内容由iTunes和iCloud备份。
Directory4 : Library/
Description: This is the top-level directory for any files that are not user data files. You typically put files in one of several standard subdirectories. iOS apps commonly use the Application Support
and Caches
subdirectories; however, you can create custom subdirectories.
- 这是非用户数据文件的任何文件的顶级目录。 您通常将文件放在几个标准子目录之一中。 iOS应用程序通常使用Application Support和Caches子目录; 但是,您可以创建自定义子目录。
Use the Library
subdirectories for any files you don’t want exposed to the user. Your app should not use these directories for user data files.
- 对于您不希望向用户公开的任何文件,请使用Library子目录。 您的应用不应将这些目录用于用户数据文件。
The contents of the Library
directory (with the exception of the Caches
subdirectory) are backed up by iTunes and iCloud.
- “Library”目录的内容(“Caches”子目录除外)由iTunes和iCloud备份。
For additional information about the Library directory and its commonly used subdirectories, see The Library Directory Stores App-Specific Files.
- 有关Library目录及其常用子目录的其他信息,请参阅库目录存储特定于应用程序的文件。
Directory5 : tmp/
Description:
Description: Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when they are no longer needed; however, the system may purge this directory when your app is not running.
- 使用此目录可以编写在应用程序启动之间不需要保留的临时文件。 您的应用程序应在不再需要时删除此目录中的文件; 但是,当您的应用未运行时,系统可能会清除此目录。
The contents of this directory are not backed up by iTunes or iCloud.
- iTunes或iCloud不会备份此目录的内容。
An iOS app may create additional directories in the Documents
, Library
, and tmp
directories. You might do this to better organize the files in those locations.
- iOS应用程序可能会在Documents,Library和tmp目录中创建其他目录。 您可以这样做以更好地组织这些位置中的文件。
For information about how to get references to the preceding directories from your iOS app, see Locating Items in the Standard Directories. For tips on where to put files, see Where You Should Put Your App’s Files.
- 有关如何从iOS应用程序获取对前面目录的引用的信息,请参阅在标准目录中查找项目。 有关放置文件的位置的提示,请参阅应放置应用程序文件的位置。
Where You Should Put Your App’s Files
// 你应该把你的应用程序的文件放在哪里
To prevent the syncing and backup processes on iOS devices from taking a long time, be selective about where you place files. Apps that store large files can slow down the process of backing up to iTunes or iCloud. These apps can also consume a large amount of a user's available storage, which may encourage the user to delete the app or disable backup of that app's data to iCloud. With this in mind, you should store app data according to the following guidelines:
- 要防止iOS设备上的同步和备份过程花费很长时间,请选择放置文件的位置。 存储大型文件的应用程序可能会降低备份到iTunes或iCloud的速度。 这些应用程序还可能消耗大量用户的可用存储空间,这可能会鼓励用户删除应用程序或禁用该应用程序数据备份到iCloud。 考虑到这一点,您应该根据以下准则存储应用数据:
-
Put user data in
Documents/
. User data generally includes any files you might want to expose to the user—anything you might want the user to create, import, delete or edit. For a drawing app, user data includes any graphic files the user might create. For a text editor, it includes the text files. Video and audio apps may even include files that the user has downloaded to watch or listen to later.- 将用户数据放在Documents /中。 用户数据通常包括您可能希望向用户公开的任何文件 - 您可能希望用户创建,导入,删除或编辑的任何文件。 对于绘图应用程序,用户数据包括用户可能创建的任何图形文件。 对于文本编辑器,它包含文本文件。 视频和音频应用程序甚至可能包含用户下载后观看或收听的文件。
-
Put app-created support files in the
Library/Application support/
directory. In general, this directory includes files that the app uses to run but that should remain hidden from the user. This directory can also include data files, configuration files, templates and modified versions of resources loaded from the app bundle.- 将应用程序创建的支持文件放在库/应用程序支持/目录中。 通常,此目录包含应用程序用于运行但应保持对用户隐藏的文件。 此目录还可以包括从应用程序包加载的数据文件,配置文件,模板和已修改的资源版本。
-
Remember that files in
Documents/
andApplication Support/
are backed up by default. You can exclude files from the backup by calling-[NSURL setResourceValue:forKey:error:]
using theNSURLIsExcludedFromBackupKey
key. Any file that can be re-created or downloaded must be excluded from the backup. This is particularly important for large media files. If your application downloads video or audio files, make sure they are not included in the backup.- 请记住,默认情况下会备份Documents /和Application Support /中的文件。 您可以使用NSURLIsExcludedFromBackupKey键调用[NSURL setResourceValue:forKey:error:]从备份中排除文件。 必须从备份中排除任何可以重新创建或下载的文件。 这对于大型媒体文件尤为重要。 如果您的应用程序下载视频或音频文件,请确保它们不包含在备份中。
-
Put temporary data in the
tmp/
directory. Temporary data comprises any data that you do not need to persist for an extended period of time. Remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device. The system will periodically purge these files when your app is not running; therefore, you cannot rely on these files persisting after your app terminates.- 将临时数据放在tmp /目录中。 临时数据包括您不需要长时间保留的任何数据。 请记住在完成这些文件后删除这些文件,以便它们不会继续消耗用户设备上的空间。 当您的应用未运行时,系统会定期清除这些文件; 因此,您的应用程序终止后,您不能依赖这些文件。
-
Put data cache files in the
Library/Caches/
directory. Cache data can be used for any data that needs to persist longer than temporary data, but not as long as a support file. Generally speaking, the application does not require cache data to operate properly, but it can use cache data to improve performance. Examples of cache data include (but are not limited to) database cache files and transient, downloadable content. Note that the system may delete theCaches/
directory to free up disk space, so your app must be able to re-create or download these files as needed.- 将数据缓存文件放在Library / Caches /目录中。 缓存数据可用于需要比临时数据持续更长时间的任何数据,但不能与支持文件一样长。 一般来说,应用程序不需要缓存数据正常运行,但它可以使用缓存数据来提高性能。 高速缓存数据的示例包括(但不限于)数据库高速缓存文件和瞬态可下载内容。 请注意,系统可能会删除Caches /目录以释放磁盘空间,因此您的应用必须能够根据需要重新创建或下载这些文件。
How the System Identifies the Type of Content in a File
- 系统如何识别文件中的内容类型
There are two primary techniques for identifying the type of content in a file:
- 有两种主要技术可用于识别文件中的内容类型:
Uniform Type Identifiers (UTIs): 统一类型标识符(UTI)
Filename extensions: 文件扩展名
A uniform type identifier is a string that uniquely identifies a class of entities considered to have a “type.” UTIs provide consistent identifiers for data that all apps and services can recognize and rely upon. They are also more flexible than most other techniques because you can use them to represent any type of data, not just files and directories. Examples of UTIs include:
- 统一类型标识符是唯一标识被认为具有“类型”的实体类的字符串.UTI为所有应用和服务可识别和依赖的数据提供一致的标识符。 它们也比大多数其他技术更灵活,因为您可以使用它们来表示任何类型的数据,而不仅仅是文件和目录。 UTI的例子包括:
public.text—A public type that identifies text data.
- 标识文本数据的公共类型。
public.jpeg—A public type that identifies JPEG image data.
- 标识JPEG图像数据的公共类型。
com.apple.bundle—An Apple type that identifies a bundle directory.
- 标识捆绑目录的Apple类型。
com.apple.application-bundle—An Apple type that identifies a bundled app.
- 标识捆绑应用的Apple类型。
Whenever a UTI-based interface is available for specifying file types, you should prefer that interface over any others. Many macOS interfaces allow you to specify UTIs corresponding to the files or directories you want to work with. For example, in the Open panel, you can use UTIs as file filters and limit the types of files the user selects to ones your app can handle. Several AppKit classes, including NSDocument, NSPasteboard, and NSImage, support UTIs. In iOS, UTIs are used to specify pasteboard types only.
- 每当基于UTI的接口可用于指定文件类型时,您应该优先于任何其他接口。 许多macOS接口允许您指定与要使用的文件或目录相对应的UTI。 例如,在“打开”面板中,您可以将UTI用作文件筛选器,并将用户选择的文件类型限制为应用程序可以处理的文件类型。 几个AppKit类,包括NSDocument,NSPasteboard和NSImage,都支持UTI。 在iOS中,UTI仅用于指定粘贴板类型。
One way the system determines the UTI for a given file is by looking at its filename extension. A filename extension is a string of characters appended to the end of a file and separated from the main filename with a period. Each unique string of characters identifies a file of a specific type. For example, the .strings extension identifies a resource file with localizable string data while the .png extension identifies a file with image data in the portable network graphics format.
- 系统确定给定文件的UTI的一种方法是查看其文件扩展名。 文件扩展名是附加到文件末尾的字符串,并使用句点与主文件名分隔。 每个唯一的字符串标识特定类型的文件。 例如,.strings扩展名标识具有可本地化字符串数据的资源文件,而.png扩展名标识具有便携式网络图形格式的图像数据的文件。
Note: Because period characters are valid characters in macOS and iOS filenames, only the characters after the last period in a filename are considered part of the filename extension. Everything to the left of the last period is considered part of the filename itself.
- 由于句点字符是macOS和iOS文件名中的有效字符,因此只有文件名中最后一个句点之后的字符才会被视为文件扩展名的一部分。 最后一个周期左边的所有内容都被视为文件名本身的一部分。
If your app defines custom file formats, you should register those formats and any associated filename extensions in your app’s Info.plist
file. The CFBundleDocumentTypes
key specifies the file formats that your app recognizes and is able to open. Entries for any custom file formats should include both a filename extension and UTI corresponding to the file contents. The system uses that information to direct files with the appropriate type to your app.
如果您的应用定义了自定义文件格式,则应在应用的Info.plist文件中注册这些格式和任何相关的文件扩展名。 CFBundleDocumentTypes键指定应用识别并能够打开的文件格式。 任何自定义文件格式的条目都应包括文件扩展名和与文件内容对应的UTI。 系统使用该信息将具有适当类型的文件定向到您的应用程序。
For more information about UTIs and how you use them, see Uniform Type Identifiers Overview. For more information about the CFBundleDocumentTypes
key, see Information Property List Key Reference.
Files Can Be Encrypted On Disk
Both macOS and iOS provide support for encrypting files on disk:
-
iOS. An iOS app can designate files that it wants to be encrypted on disk. When the user unlocks a device containing encrypted files, the system creates a decryption key that allows the app to access its encrypted files. When the user locks the device, though, the decryption key is destroyed to prevent unauthorized access to the files.
- iOS应用程序可以指定要在磁盘上加密的文件。 当用户解锁包含加密文件的设备时,系统会创建一个解密密钥,允许该应用访问其加密文件。 但是,当用户锁定设备时,破解解密密钥以防止对文件的未授权访问。
In iOS, apps that take advantage of disk-based encryption need to be discontinue the use of encrypted files when the user locks the device. Because locking the device destroys the decryption keys, access to encrypted files is limited to when the device is unlocked. If your iOS app can run in the background while the device is locked, it must do so without access to any of its encrypted files. Because encrypted disks in macOS are always accessible while the computer is running, macOS apps do not need to do anything special to handle disk-level encryption.
- 在iOS中,利用基于磁盘的加密的应用程序需要在用户锁定设备时停止使用加密文件。 由于锁定设备会破坏解密密钥,因此对加密文件的访问仅限于设备解锁时。 如果您的iOS应用程序可以在设备锁定时在后台运行,则必须在不访问任何加密文件的情况下执行此操作。 由于macOS中的加密磁盘在计算机运行时始终可以访问,因此macOS应用程序无需执行任何特殊操作即可处理磁盘级加密。
For more information about working with encrypted files in iOS, see App Programming Guide for iOS.
Files, Concurrency, and Thread Safety
Because file-related operations involve interacting with the hard disk and are therefore slow compared to most other operations, most of the file-related interfaces in iOS and macOS are designed with concurrency in mind. Several technologies incorporate asynchronous operation into their design and most others can execute safely from a dispatch queue or secondary thread. Table 1-4 lists some of the key technologies discussed in this document and whether they are safe to use from specific threads or any thread. For specific information about the capabilities of any interface, see the reference documentation for that interface.
- 由于与文件相关的操作涉及与硬盘交互,因此与大多数其他操作相比较慢,因此iOS和macOS中的大多数与文件相关的接口都考虑了并发性。 有几种技术将异步操作合并到其设计中,而大多数其他技术可以从调度队列或辅助线程安全地执行。 表1-4列出了本文档中讨论的一些关键技术,以及它们是否可以安全地从特定线程或任何线程使用。 有关任何接口功能的特定信息,请参阅该接口的参考文档。
-
NSFileManager
For most tasks, it is safe to use the default NSFileManager object simultaneously from multiple background threads. The only exception to this rule is tasks that interact with the file manager’s delegate. When using a file manager object with a delegate, it is recommended that you create a unique instance of the NSFileManager class and use your delegate with that instance. You should then use your unique instance from one thread at a time.
- 对于大多数任务,可以安全地从多个后台线程同时使用默认的NSFileManager对象。 此规则的唯一例外是与文件管理器委托交互的任务。 将文件管理器对象与委托一起使用时,建议您创建NSFileManager类的唯一实例,并将该委托与该实例一起使用。 然后,您应该一次使用一个线程中的唯一实例。
- Grand Central Dispatch
GCD itself is safe to use from any thread. However, you are still responsible for writing your blocks in a way that is thread safe.
- GCD本身可以安全地从任何线程使用。 但是,您仍然负责以线程安全的方式编写块。
-
NSFileHandle
,
NSData, Cocoa streams
Most of the Foundation objects you use to read and write file data can be used from any single thread but should not be used from multiple threads simultaneously.
- 您用于读取和写入文件数据的大多数Foundation对象都可以在任何单个线程中使用,但不应同时从多个线程使用。
- Open and Save panels
Because they are part of your user interface, you should always present and manipulate the Open and Save panels from your app’s main thread.
- 因为它们是用户界面的一部分,所以应始终在应用程序的主线程中显示和操作“打开”和“保存”面板。
- POSIX routines
The POSIX routines for manipulating files are generally designed to operate safely from any thread. For details, see the corresponding man pages.
- 用于操作文件的POSIX例程通常设计为从任何线程安全地操作。 有关详细信息,请参见相应的手册页。
-
NSURL
and
NSString
The immutable objects you use to specify paths are safe to use from any thread. Because they are immutable, you can also refer to them from multiple threads simultaneously. Of course, the mutable versions of these objects should be used from only one thread at a time.
- 用于指定路径的不可变对象可以安全地从任何线程使用。 因为它们是不可变的,所以您也可以同时从多个线程中引用它们。 当然,这些对象的可变版本一次只能在一个线程中使用。
-
NSEnumerator and its subclasses
Enumerator objects are safe to use from any single thread but should not be used from multiple threads simultaneously.
- 枚举器对象可以安全地从任何单个线程使用,但不应同时从多个线程使用。
Even if you use an thread-safe interface for manipulating a file, problems can still arise when multiple threads or multiple processes attempt to act on the same file. Although there are safeguards to prevent multiple clients from modifying a file at the same time, those safeguards do not always guarantee exclusive access to the file at all times. (Nor should you attempt to prevent other processes from accessing shared files.) To make sure your code knows about changes made to shared files, use file coordinators to manage access to those files. For more information about file coordinators, see The Role of File Coordinators and Presenters
- 即使您使用线程安全接口来操作文件,当多个线程或多个进程尝试对同一文件执行操作时,仍会出现问题。 尽管存在防止多个客户端同时修改文件的安全措施,但这些安全措施并不总能保证对文件的独占访问。 (您也不应该尝试阻止其他进程访问共享文件。)要确保您的代码知道对共享文件所做的更改,请使用文件协调器来管理对这些文件的访问。 有关文件协调器的更多信息,请参阅文件协调器和演示者的角色