文件系统操作全解析
立即解锁
发布时间: 2025-08-24 01:06:49 阅读量: 1 订阅数: 37 


Objective-C编程与应用开发实战
# 文件系统操作全解析
## 1. 文件夹与位置管理
在管理文件夹内容、移动、复制或删除项目时,`NSFileManager` 是首选的 API。通常通过调用 `+defaultManager` 获取其单例实例,它提供了对文件系统进行更改所需的所有方法,还能定位文件系统中的各种标准位置,如缓存数据文件夹、用户的 `Documents` 文件夹、`Applications` 文件夹等。
### 1.1 文件夹层级与域系统
OS X 采用了定义明确的文件夹层级结构,不同类型的项目有标准的存放位置。同时,它还提供了域系统,许多文件夹存在于不同的域中:
- **用户域**:针对单个用户,位于用户主文件夹内。
- **本地域**:适用于所有用户,基于系统卷的根目录。
- **系统域**:系统默认值,位于系统卷的 `/System` 内。
- **网络域**:由网络管理员设置的项目,位于从 OS X 服务器挂载的文件系统上,但如今很少使用。
这些域有特定的优先级顺序:用户域 > 本地域 > 网络域 > 系统域。例如,在搜索偏好设置时,系统会先检查用户主文件夹中的偏好设置,然后是根 `Library` 文件夹、网络文件夹,最后是系统文件夹(存放苹果提供的默认值)。
### 1.2 标准系统文件夹
许多系统文件夹类型通过 `<Foundation/NSPathUtilities.h>` 中定义的整数常量指定,常见的标准系统文件夹如下表所示:
| 标识符 | 描述 |
| --- | --- |
| `NSLibraryDirectory` | `Library` 文件夹,包含文档、支持和配置文件。 |
| `NSDocumentDirectory` | 用户的 `Documents` 文件夹,仅适用于用户域。 |
| `NSCachesDirectory` | `Library` 的子文件夹,用于存储缓存(但可替换)数据,以便快速访问。 |
| `NSApplicationSupportDirectory` | `Library` 的另一个子文件夹,应用程序通常在此存储非用户数据。 |
| `NSApplicationScriptsDirectory` | 当前应用程序的 `AppleScripts` 应存储的文件夹(仅在用户域)。 |
| `NSItemReplacementDirectory` | 用于原子文件交换操作的目录位置,与提供的 URL 在同一卷上。 |
| `NSTrashDirectory` | 与给定 URL 对应的回收站文件夹位置,OS X 10.8 可用。 |
### 1.3 定位文件夹的方法
`NSFileManager` 提供了两种定位这些文件夹的方法:
- **`-URLsForDirectory:inDomains:`**:返回指定目录类型在多个指定域中的搜索顺序的 URL 列表。域通过位域指定,多个值可以按位或组合以处理多个域。但要注意,返回的 URL 列表中的文件夹不一定实际存在于磁盘上,可能需要手动创建。
- **`-URLForDirectory:inDomain:appropriateForURL:create:error:`**:当你只需要查找单个目录时,这个 API 更合适。它还允许指定一个 URL,用于定位适当的卷特定的回收站位置或提供项目替换的规范 URL。此外,还可以请求在目录不存在时创建它。以下是使用示例:
```objc
// locate the appropriate Trash folder for an item we want to move to the trash
// this will return the URL of a user-specific folder on the same volume as the
// item to be trashed.
NSURL * trashFolder = [[NSFileManager defaultManager] URLForDirectory: NSTrashDirectory
inDomain: NSUserDomainMask
appropriateForURL: itemURL
create: YES
error: &error];
// move the item to the trash
NSURL * trashedItemURL = [trashFolder URLByAppendingPathComponent:
[itemURL lastPathComponent]];
[[NSFileManager defaultManager] moveItemAtURL: itemURL
toURL: trashedItemURL
error: &error];
// Get a temporary folder to write out our new data ready to swap out with the old
NSURL * swapFolder = [[NSFileManager defaultManager] URLForDirectory:
NSItemReplacementDirectory
inDomain: NSUserDomainMask
appropriateForURL: itemURL
create: YES
error: &error];
NSURL * tmpItemURL = [swapFolder URLByAppendingPathComponent:
[itemURL lastPathComponent]];
// Generate the new content
[self generateContentAtURL: tmpItemURL];
// now swap the new item with the old
[[NSFileManager defaultManager] replaceItemAtURL: itemURL
withItemAtURL: tmpItemURL
backupItemName: nil
options: 0
replacementItemURL: NULL
error: &error];
```
### 1.4 其他 NSFileManager API
除了上述方法,`NSFileManager` 还提供了一些用于移动项目和访问其属性的方法,如下表所示:
| 方法 | 描述 |
| --- | --- |
| `copyItemAtURL:toURL:error:` | 在目标 URL 处复制给定项目。 |
| `moveItemAtURL:toURL:error:` | 将项目移动到新位置。 |
| `removeItemAtURL:error:` | 删除给定 URL 处的文件或文件夹。 |
| `linkItemAtURL:toURL:error:` | 在现有项目和新位置之间创建硬链接。 |
| `trashItemAtURL:resultingItemURL:error:` | 将指定项目移动到用户的回收站文件夹(OS X 10.8 可用)。 |
| `createSymbolicLinkAtURL:withDestinationURL: error:` | 在指定位置创建指向给定 URL 的符号链接。 |
| `createDirectoryAtPath:withIntermediateDirectories:attributes:error:` | 创建具有给定属性的新文件夹,可选择创建任何缺失的父文件夹。 |
| `attributesOfItemAtPath:error:` | 获取给定路径下文件的各种属性的 `NSDictionary`。 |
### 1.5 硬链接和符号链接
当上述方法提到链接时,指的是文件系统创建一种文件的能力,这种文件本身不包含数据,只是引用另一个文件。在 OS X 和 iOS 上有两种类型的链接:
- **硬链接**:本质上与常规文件相同,链接的目标和链接本身直接引用物理媒体上的相同存储块。当文件放入文件夹时,会创建硬链接将描述文件的文件夹条目与磁盘上的实际存储关联起来。创建现有文件的硬链接只是创建另一个指向相同存储的文件夹条目。只有当所有指向这些存储块的硬链接都被删除后,系统才会回收这些存储块。
- **符号链接**:是包含绝对或相对路径的常规文件,核心文件系统 API 会自动遍历它们。符号链接文件本身带有特殊的模式标志,告诉系统以不同方式处理它。除非使用特殊的不跟随链接的 API,否则与符号链接文件的任何交互都会确定其目标路径并与目标文件进行交互。
硬链接在目标文件移动或重命名时仍然有效,而符号链接基于路径,可能会失效。但通常更倾向于使用符号链接,因为它们更容易识别为链接。硬链接与真实文件难以区分,在遍历文件系统时,看到同一个文件的两个硬链接会将文件大小计算两次。
### 1.6 检查文件夹内容
`NSFileManager` 提供了多种检查文件夹内容的方法。可以使用 `-contentsOfDirectoryAtPath:error:` 获取单个文件夹的内容作为数组,但最灵活的方式是使用 `NSDirectoryEnumerator`。可以在创建枚举器时指定一些细粒度的选项,如枚举的深度和是否预取 `NSURL` 属性。它提供了获取下一个项目、获取其属性以及在枚举期间跳过特定子文件夹的方法。以下是一个使用示例:
```objc
NSURL * myURL = [NSURL fileURLWithPathComponents: @[ NSHomeDirectory(), @"Pictures" ]];
NSArray * properties = @[ NSURLLocalizedNameKey, NSURLLocalizedTypeDescriptionKey, NSURLFileSizeKey ];
NSDirectoryEnumerationOptions options = NSDirectoryEnumerationSkipsPackageDescendants;
NSDirectoryEnumerator * dirEnum = [[NSFileManager defaultManager] enumeratorAtURL: myURL
includingPropertiesForKeys: properties options: options
errorHandler: ^BOOL(NSURL *url, NSError *error) {
NSLog(@"Error looking at URL '%@': %@", url, error);
// continue enumerating
return ( YES );
}];
NSURL * url;
while ( (url = [dirEnum nextObject]) != nil )
{
NSDictionary * attrs = [url resourceValuesForKeys: properties error: NULL];
NSNumber * size = [attrs objectForKey: NSURLFileSizeKey];
NSString * sizeStr = nil;
i
```
0
0
复制全文
相关推荐









