`
慭慭流觞
  • 浏览: 45583 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

NSFile​Manager

    博客分类:
  • iOS
阅读更多

NSFileManager is Foundation's high-level API for working with file systems. It abstracts Unix and Finder internals, providing a convenient way to create, read, move, copy, and delete files & directories on local or networked drives, as well as iCloud ubiquitous containers.

File systems are a complex topic, with decades of history, vestigial complexities, and idiosyncrasies, and is well outside the scope of a single article. And since most applications don't often interact with the file system much beyond simple file operations, one can get away with only knowing the basics.

What follows are some code samples for your copy-pasting pleasure. Use them as a foundation for understanding how to adjust parameters to your particular use case:

Common Tasks

Throughout the code samples is the magical incantation NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES). This may be tied with KVO as one of the worst APIs in Cocoa. Just know that this returns an array containing the user documents directory as the first object. Thank goodness for the inclusion of NSArray -firstObject.

Determining If A File Exists

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"file.txt"];
BOOL fileExists = [fileManager fileExistsAtPath:filePath];

Listing All Files In A Directory

NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
NSArray *contents = [fileManager contentsOfDirectoryAtURL:bundleURL
                               includingPropertiesForKeys:@[]
                                                  options:NSDirectoryEnumerationSkipsHiddenFiles
                                                    error:nil];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"pathExtension ENDSWITH '.png'"];
for (NSString *path in [contents filteredArrayUsingPredicate:predicate]) {
    // Enumerate each .png file in directory
}

Recursively Enumerating Files In A Directory

NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtURL:bundleURL
                                      includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey]
                                                         options:NSDirectoryEnumerationSkipsHiddenFiles
                                                    errorHandler:^BOOL(NSURL *url, NSError *error)
{
    NSLog(@"[Error] %@ (%@)", error, url);
}];

NSMutableArray *mutableFileURLs = [NSMutableArray array];
for (NSURL *fileURL in enumerator) {
    NSString *filename;
    [fileURL getResourceValue:&filename forKey:NSURLNameKey error:nil];

    NSNumber *isDirectory;
    [fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];

    // Skip directories with '_' prefix, for example
    if ([filename hasPrefix:@"_"] && [isDirectory boolValue]) {
        [enumerator skipDescendants];
        continue;
    }

    if (![isDirectory boolValue]) {
        [mutableFileURLs addObject:fileURL];
    }
}

Create a Directory

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *imagesPath = [documentsPath stringByAppendingPathComponent:@"images"];
if (![fileManager fileExistsAtPath:imagesPath]) {
    [fileManager createDirectoryAtPath:imagesPath withIntermediateDirectories:NO attributes:nil error:nil];
}

Deleting a File

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"image.png"];
NSError *error = nil;

if (![fileManager removeItemAtPath:filePath error:&error]) {
    NSLog(@"[Error] %@ (%@)", error, filePath);
}

Determine the Creation Date of a File

NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"Document.pages"];

NSDate *creationDate = nil;
if ([fileManager fileExistsAtPath:filePath]) {
    NSDictionary *attributes = [fileManager attributesOfItemAtPath:filePath error:nil];
    creationDate = attributes[NSFileCreationDate];
}

There are a number of file attributes that are made accessible through NSFileManager, which can be fetched with -attributesOfItemAtPath:error:, and other methods:

File Attribute Keys

  • NSFileAppendOnly: The key in a file attribute dictionary whose value indicates whether the file is read-only.
  • NSFileBusy: The key in a file attribute dictionary whose value indicates whether the file is busy.
  • NSFileCreationDate: The key in a file attribute dictionary whose value indicates the file's creation date.
  • NSFileOwnerAccountName: The key in a file attribute dictionary whose value indicates the name of the file's owner.
  • NSFileGroupOwnerAccountName: The key in a file attribute dictionary whose value indicates the group name of the file's owner.
  • NSFileDeviceIdentifier: The key in a file attribute dictionary whose value indicates the identifier for the device on which the file resides.
  • NSFileExtensionHidden: The key in a file attribute dictionary whose value indicates whether the file's extension is hidden.
  • NSFileGroupOwnerAccountID: The key in a file attribute dictionary whose value indicates the file's group ID.
  • NSFileHFSCreatorCode: The key in a file attribute dictionary whose value indicates the file's HFS creator code.
  • NSFileHFSTypeCode: The key in a file attribute dictionary whose value indicates the file's HFS type code.
  • NSFileImmutable: The key in a file attribute dictionary whose value indicates whether the file is mutable.
  • NSFileModificationDate: The key in a file attribute dictionary whose value indicates the file's last modified date.
  • NSFileOwnerAccountID: The key in a file attribute dictionary whose value indicates the file's owner's account ID.
  • NSFilePosixPermissions: The key in a file attribute dictionary whose value indicates the file's Posix permissions.
  • NSFileReferenceCount: The key in a file attribute dictionary whose value indicates the file's reference count.
  • NSFileSize: The key in a file attribute dictionary whose value indicates the file's size in bytes.
  • NSFileSystemFileNumber: The key in a file attribute dictionary whose value indicates the file's filesystem file number.
  • NSFileType: The key in a file attribute dictionary whose value indicates the file's type.

  • NSDirectoryEnumerationSkipsSubdirectoryDescendants: Perform a shallow enumeration; do not descend into directories.

  • NSDirectoryEnumerationSkipsPackageDescendants: Do not descend into packages.

  • NSDirectoryEnumerationSkipsHiddenFiles: Do not enumerate hidden files.

NSFileManagerDelegate

NSFileManager may optionally set a delegate to verify that it should perform a particular file operation. This allows the business logic of, for instance, which files to protect from deletion, to be factored out of the controller.

There are four kinds of methods in the <NSFileManagerDelegate> protocol, each with a variation for working with paths, as well as methods for error handling.

  • -fileManager:shouldMoveItemAtURL:toURL:
  • -fileManager:shouldCopyItemAtURL:toURL:
  • -fileManager:shouldRemoveItemAtURL:
  • -fileManager:shouldLinkItemAtURL:toURL:

If you were wondering when you might alloc init your own NSFileManager rather than using the shared instance, this is it. As per the documentation:

If you use a delegate to receive notifications about the status of move, copy, remove, and link operations, you should create a unique instance of the file manager object, assign your delegate to that object, and use that file manager to initiate your operations.

NSFileManager *fileManager = [[NSFileManager alloc] init];
fileManager.delegate = delegate;

NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
NSArray *contents = [fileManager contentsOfDirectoryAtURL:bundleURL
                               includingPropertiesForKeys:@[]
                                                  options:NSDirectoryEnumerationSkipsHiddenFiles
                                                    error:nil];

for (NSString *filePath in contents) {
    [fileManager removeItemAtPath:filePath error:nil];
}

CustomFileManagerDelegate.m

#pragma mark - NSFileManagerDelegate

- (BOOL)fileManager:(NSFileManager *)fileManager
shouldRemoveItemAtURL:(NSURL *)URL
{
    return ![[[URL lastPathComponent] pathExtension] isEqualToString:@"pdf"];
}

Ubiquitous Storage

Documents can also be moved to iCloud. If you guessed that this would be anything but straight forward, you'd be 100% correct.

This is another occasion when you'd alloc init your own NSFileManager rather than using the shared instance. Because URLForUbiquityContainerIdentifier: and setUbiquitous:itemAtURL:destinationURL:error: are blocking calls, this entire operation needs to be dispatched to a background queue.

Move Item to Ubiquitous Storage

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    NSFileManager *fileManager = [[NSFileManager alloc] init];
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSURL *fileURL = [NSURL fileURLWithPath:[documentsPath stringByAppendingPathComponent:@"Document.pages"]];

    // Defaults to first listed in entitlements when `nil`; should replace with real identifier
    NSString *identifier = nil;

    NSURL *ubiquitousContainerURL = [fileManager URLForUbiquityContainerIdentifier:identifier];
    NSURL *ubiquitousFileURL = [ubiquitousContainerURL URLByAppendingPathComponent:@"Document.pages"];

    NSError *error = nil;
    BOOL success = [fileManager setUbiquitous:YES
                                    itemAtURL:fileURL
                               destinationURL:ubiquitousFileURL
                                        error:&error];
    if (!success) {
        NSLog(@"[Error] %@ (%@) (%@)", error, fileURL, ubiquitousFileURL);
    }
});

You can find more information about ubiquitous document storage in Apple's "iCloud File Management" document.


There's a lot to know about file systems, but as an app developer, it's mostly an academic exercise. Now don't get me wrong—academic exercises are great! But they don't ship code. NSFileManager allows you to ignore most of the subtlety of all of this and get things done.

see:http://nshipster.com/nsfilemanager/

分享到:
评论

相关推荐

    极简网盘veno-file-manager-v3.5.6.zip

    【标题】"极简网盘veno-file-manager-v3.5.6.zip"指的是一个针对网盘服务的软件包,其版本号为v3.5.6。这通常是一个开源或者商业软件的更新版本,提供了简化操作、高效管理个人或团队云端存储文件的功能。 【描述】...

    群晖FileManager管理工具

    群晖FileManager是一款强大的远程文件管理工具,专为群晖NAS(网络附加存储)用户设计,提供了便捷、高效的方式来管理和组织存储在群晖设备上的数据。该工具的主要特点是其直观的界面和丰富的功能集,使用户能够轻松...

    dde-file-manager脚本

    解决在linux mint下使用微信“在文件夹中显示”菜单无效的问题,直接放在/usr/bin/或~/.local/bin下都可以,然后执行 chmod +x dde-file-manager

    Laravel开发-laravel_file_manager

    在本文中,我们将深入探讨基于Laravel框架的文件管理器包——laravel_file_manager。这个包是由ArtinCMS官方提供的,旨在为Laravel开发者提供一个高效、便捷的文件管理解决方案,帮助他们更好地处理应用程序中的文件...

    Laravel开发-laravel-file-manager

    在本文中,我们将深入探讨如何在 Laravel 框架中使用 "laravel-file-manager" 这一工具,以便实现高效且用户友好的文件上传和编辑功能。"laravel-file-manager" 是专为 Laravel 5 设计的一个插件,它与 Keccakier 富...

    Channel File Manager

    《Channel File Manager:WII WAD 文件安装器详解》 在WII游戏机的世界里,Channel File Manager是一款不可或缺的工具,特别是对于那些热衷于自定义和扩展其功能的用户而言。这款软件的核心功能在于帮助用户管理和...

    FileManager(在线文件管理)

    《 FileManager:在线文件管理的深度探索》 在线文件管理,作为一种高效便捷的文件处理方式,已经成为现代工作生活的重要组成部分。FileManager作为一款优秀的在线文件管理工具,它的出现极大地优化了我们对电子...

    (Swift)FileManager(文件管理)

    Swift中的`FileManager`是苹果iOS、macOS、watchOS和tvOS平台上用于处理文件系统操作的核心类。这个类提供了各种方法来创建、删除、移动、复制以及查询文件和目录。在开发过程中,理解并熟练使用`FileManager`对于...

    Synology File Manager-1.0.2-0017.exe

    Synology File Manager

    Simple-File-Manager,一个简单的文件管理器,用于浏览和编辑文件和目录。.zip

    《Simple-File-Manager:一款开源的文件管理器详解》 在数字时代,文件管理是日常操作中的重要一环,而Simple-File-Manager则是一款专为此目的设计的开源工具。这款文件管理器允许用户方便地浏览和编辑本地设备上的...

    fileManager

    "fileManager"是一个基于Java语言开发的文件管理器系统,主要设计用于命令行操作,它提供了丰富的文件和文件夹管理功能。在这个系统中,用户可以通过简单的命令行指令来执行各种文件操作,比如创建新的文件夹、复制...

    filemanager-0.0.2.zip

    《filemanager-0.0.2.zip:探索KindEditor与Kind-FileManager的开源魅力》 在互联网技术高速发展的今天,HTML编辑器已经成为网页内容创作不可或缺的一部分。KindEditor(http://kindeditor.org/)是一个备受赞誉的...

    node-file-manager, 基于 Koa angular.js 和 Bootstrap的node.js 文件管理器web服务器.zip

    node-file-manager, 基于 Koa angular.js 和 Bootstrap的node.js 文件管理器web服务器 屏幕快照 用法 npm install -g node-file-manager node-file-manager -p 8080 -d/path/to/或者 git clone https://github

    FileManager_filemanager_FileManager_itselflba_java_

    【标题】"FileManager_filemanager_FileManager_itselflba_java_" 指的是一款基于Java编程语言的文件管理器源码项目,名为"FileManager"。这个项目由itselflba开发,旨在提供一个基础的文件管理和操作功能,对于初学...

    angular-filemanager-master

    **Angular FileManager 深度解析** Angular FileManager 是一个基于 AngularJS 框架开发的开源、响应式的文件管理系统。这个项目由 Joni2back 创建并维护,它提供了一个直观的用户界面,允许用户轻松地浏览、上传、...

    Laravel开发-filemanager

    在本文中,我们将深入探讨如何在Laravel框架中使用`filemanager`来实现高效便捷的文件管理和操作。`Laravel开发-filemanager`是专为Laravel5设计的一个强大的文件管理工具,它提供了一系列实用功能,如重命名、创建...

    simogeo-Filemanager

    "simogeo-Filemanager" 是一款专为文本编辑和管理设计的应用程序,它具有集成CKEditor的能力,使得用户在处理文本内容时能够享受到更为高效和便捷的体验。这款工具在IT领域中扮演着重要的角色,特别是在需要进行大量...

    Laravel开发-laravel-filemanager

    在本文中,我们将深入探讨 Laravel 开发中的一个重要组件——laravel-filemanager,它是一个专门为 Laravel 5 框架以及 Keccakcer 和 TinyMCE 这样的富文本编辑器设计的文件上传和编辑工具。这个工具极大地简化了在 ...

    File-Manager-UI-Wpf-master.7z

    【标题】"File-Manager-UI-Wpf-master.7z" 涉及的是一个基于WPF(Windows Presentation Foundation)的文件管理器用户界面项目。这个压缩包包含了一个完整的开发环境,供开发者进行学习和使用。 【描述】"自用资源...

    FIleManager

    FIle manager for phone and sd card

Global site tag (gtag.js) - Google Analytics