美文网首页
Managing Files and Directories

Managing Files and Directories

作者: ngugg | 来源:发表于2018-10-29 12:49 被阅读0次

相关链接:
https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/ManagingFIlesandDirectories/ManagingFIlesandDirectories.html#//apple_ref/doc/uid/TP40010672-CH6-SW1

Some of the most basic operations involving files and directories are creating them and moving them around the file system. These operations are how your app builds the file system structure it needs to perform its tasks. For most operations, the NSFileManager class should offer the functionality you need to create and manipulate files. In the rare cases where it does not, you need to use BSD-level functions directly.

  • 涉及文件和目录的一些最基本的操作是创建它们并在文件系统中移动它们。 这些操作是您的应用程序构建执行其任务所需的文件系统结构的方式。 对于大多数操作,NSFileManager类应提供创建和操作文件所需的功能。 在极少数情况下,您需要直接使用BSD级功能。

Creating New Files and Directories Programmatically

Creating files and directories is a basic part of file management. Typically, you create custom directories to organize the files created by your code. For example, you might create some custom directories in your app’s Application Support directory to store any private data files managed by your app. And there are many ways to create files.

  • 创建文件和目录是文件管理的基本部分。 通常,您可以创建自定义目录来组织代码创建的文件。 例如,您可以在应用程序的“应用程序支持”目录中创建一些自定义目录,以存储应用程序管理的任何私有数据文件。 有很多方法可以创建文件。

Creating Directories

When you want to create a custom directory, you do so using the methods of NSFileManager. A process can create directories anywhere it has permission to do so, which always includes the current home directory and may include other file system locations as well. You specify the directory to create by building a path to it and passing your NSURL or NSString object to one of the following methods:
如果要创建自定义目录,可以使用NSFileManager的方法。 进程可以在有权限的任何地方创建目录,该目录始终包括当前主目录,并且还可以包括其他文件系统位置。 您可以通过构建要创建的路径并将NSURL或NSString对象传递给以下方法之一来指定要创建的目录:

Listing 6-1 shows how to create a custom directory for app files inside the ~/Library/Application Support directory. This method creates the directory if it does not exist and returns the path to the directory to the calling code. Because this method touches the file system every time, you would not want to call this method repeatedly to retrieve the URL. Instead, you might call it once and then cache the returned URL.

  • 清单6-1显示了如何在〜/ Library / Application Support目录中为app文件创建自定义目录。 如果该目录不存在,则此方法创建该目录,并将该目录的路径返回给调用代码。 由于此方法每次都会触及文件系统,因此您不希望重复调用此方法来检索URL。 相反,您可以调用一次,然后缓存返回的URL。

Listing 6-1 Creating a custom directory for app files

- (NSURL*)applicationDirectory
{
    NSString* bundleID = [[NSBundle mainBundle] bundleIdentifier];
    NSFileManager*fm = [NSFileManager defaultManager];
    NSURL*    dirPath = nil;
 
    // Find the application support directory in the home directory.
    NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory
                                    inDomains:NSUserDomainMask];
    if ([appSupportDir count] > 0)
    {
        // Append the bundle ID to the URL for the
        // Application Support directory
        dirPath = [[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:bundleID];
 
        // If the directory does not exist, this method creates it.
        // This method is only available in macOS 10.7 and iOS 5.0 or later.
        NSError*    theError = nil;
        if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES
                   attributes:nil error:&theError])
        {
            // Handle the error.
 
            return nil;
        }
    }
 
    return dirPath;
}

If your code needs to run in OS X 10.6 and earlier, you can replace any calls to the createDirectoryAtURL:withIntermediateDirectories:attributes:error:method with a similar call to thecreateDirectoryAtPath:withIntermediateDirectories:attributes:error: method. The only change you have to make is to pass a string-based path instead of a URL as the first parameter. However, the NSURL class defines a path method that returns a string-based version of its path.

  • 如果您的代码需要在OS X 10.6及更早版本中运行,则可以替换对createDirectoryAtURL:withIntermediateDirectories:attributes:error:方法的任何调用,并调用thecreateDirectoryAtPath:withIntermediateDirectories:attributes:error:方法。 您必须做的唯一更改是传递基于字符串的路径而不是URL作为第一个参数。 但是,NSURL类定义了一个路径方法,该方法返回其路径的基于字符串的版本。

The NSFileManager methods are the preferred way to create new directories because of their simplicity. However, you can also use the mkdir function to create directories yourself. If you do so, you are responsible for creating intermediate directories and handling any errors that occur.

  • NSFileManager方法是创建新目录的首选方法,因为它们非常简单。 但是,您也可以使用mkdir函数自己创建目录。 如果这样做,您负责创建中间目录并处理发生的任何错误。

Creating New Files

There are two parts to creating a file: creating a record for the file in the file system and filling the file with content. All of the high-level interfaces for creating files perform both tasks at the same time, usually filling the file with the contents of an NSData or NSString object and then closing the file. You can also use lower-level functions to create an empty file and obtain a file descriptor that you can then use to fill the file with data. Some of the routines you can use to create files are:
创建文件有两个部分:在文件系统中为文件创建记录并使用内容填充文件。 用于创建文件的所有高级接口同时执行这两个任务,通常使用NSData或NSString对象的内容填充文件,然后关闭文件。 您还可以使用较低级别的函数来创建空文件并获取文件描述符,然后可以使用该文件描述符来使用数据填充文件。 您可以用来创建文件的一些例程是:

Note: Any files you create inherit the permissions associated with the current user and process.

  • 您创建的任何文件都会继承与当前用户和进程关联的权限。

When writing the contents of a new file all at once, the system routines typically close the file after writing the contents to disk. If the routine returns a file descriptor, you can use that descriptor to continue reading and writing from the file. For information on how to read and write the contents of a file, see Techniques for Reading and Writing Files Without File Coordinators.

  • 在一次性写入新文件的内容时,系统例程通常在将内容写入磁盘后关闭文件。 如果例程返回文件描述符,则可以使用该描述符继续从文件读取和写入。 有关如何读取和写入文件内容的信息,请参阅无文件协调器的读取和写入文件的技术。

Copying and Moving Files and Directories

To copy items around the file system, the NSFileManager class provides the copyItemAtURL:toURL:error: and copyItemAtPath:toPath:error: methods. To move files use the moveItemAtURL:toURL:error: or moveItemAtPath:toPath:error: methods.

  • 要复制文件系统周围的项目,NSFileManager类提供copyItemAtURL:toURL:error:和copyItemAtPath:toPath:error:methods。 要移动文件,请使用moveItemAtURL:toURL:error:或moveItemAtPath:toPath:error:methods。

The preceding methods move or copy a single file or directory at a time. When moving or copying a directory, the directory and all of its contents are affected. The semantics for move and copy operations are the same as in the Finder. Move operations on the same volume do not cause a new version of the item to be created. Move operations between volumes behave the same as a copy operation. And when moving or copying items, the current process must have permission to read the items and move or copy them to the new location.

  • 上述方法一次移动或复制单个文件或目录。 移动或复制目录时,目录及其所有内容都会受到影响。 移动和复制操作的语义与Finder中的语义相同。 在同一卷上移动操作不会导致创建项目的新版本。 卷之间的移动操作与复制操作的行为相同。 移动或复制项目时,当前进程必须具有读取项目并将其移动或复制到新位置的权限。

Move and copy operations can potentially take a long time to complete, and the NSFileManager class performs these operations synchronously. Therefore, it is recommended that you execute any such operations on a concurrent dispatch queue and not on your app’s main thread. Listing 6-2 shows an example that does just that by asynchronously creating a backup of a fictional app’s private data. (For the sake of the example, the private data is located in the ~/Library/Application Support/bundleID/Data directory, where bundleID is the actual bundle identifier of the app.) If the first attempt to copy the directory fails, this method checks to see whether a previous backup exists and removes it if it does. It then proceeds to try again and aborts if it fails a second time.

  • 移动和复制操作可能需要很长时间才能完成,NSFileManager类会同步执行这些操作。 因此,建议您在并发调度队列上执行任何此类操作,而不是在应用程序的主线程上执行。 清单6-2显示了一个通过异步创建虚构应用程序私有数据备份的示例。 (为了示例,私有数据位于〜/ Library / Application Support / bundleID / Data目录中,其中bundleID是应用程序的实际包标识符。)如果第一次尝试复制目录失败,则 方法检查以前的备份是否存在,如果存在,则将其删除。 然后它再次尝试并在第二次失败时中止。

Listing 6-2 Copying a directory asynchronously

- (void)backupMyApplicationData {
   // Get the application's main data directory
   NSArray* theDirs = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory
                                 inDomains:NSUserDomainMask];
   if ([theDirs count] > 0)
   {
      // Build a path to ~/Library/Application Support/<bundle_ID>/Data
      // where <bundleID> is the actual bundle ID of the application.
      NSURL* appSupportDir = (NSURL*)[theDirs objectAtIndex:0];
      NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
      NSURL* appDataDir = [[appSupportDir URLByAppendingPathComponent:appBundleID]
                               URLByAppendingPathComponent:@"Data"];
 
      // Copy the data to ~/Library/Application Support/<bundle_ID>/Data.backup
      NSURL* backupDir = [appDataDir URLByAppendingPathExtension:@"backup"];
 
      // Perform the copy asynchronously.
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         // It's good habit to alloc/init the file manager for move/copy operations,
         // just in case you decide to add a delegate later.
         NSFileManager* theFM = [[NSFileManager alloc] init];
         NSError* anError;
 
         // Just try to copy the directory.
         if (![theFM copyItemAtURL:appDataDir toURL:backupDir error:&anError]) {
            // If an error occurs, it's probably because a previous backup directory
            // already exists.  Delete the old directory and try again.
            if ([theFM removeItemAtURL:backupDir error:&anError]) {
               // If the operation failed again, abort for real.
               if (![theFM copyItemAtURL:appDataDir toURL:backupDir error:&anError]) {
                  // Report the error....
               }
            }
         }
 
      });
   }
}

For details on how to use the NSFileManager methods, see NSFileManager Class Reference.

  • 有关如何使用NSFileManager方法的详细信息,请参阅NSFileManager类参考。

Deleting Files and Directories

To delete files and directories, use the following methods of the NSFileManager class:
要删除文件和目录,请使用NSFileManager类的以下方法:

When using these methods to delete files, realize that you are permanently removing the files from the file system; these methods do not move the file to the Trash where it can be recovered later.

  • 使用这些方法删除文件时,请意识到您要从文件系统中永久删除文件; 这些方法不会将文件移动到可在以后恢复的废纸篓。

For details on how to use the NSFileManager methods, see NSFileManager Class Reference.

  • 有关如何使用NSFileManager方法的详细信息,请参阅NSFileManager类参考。

Creating and Handling Invisible Files

  • 创建和处理不可见的文件

In macOS, you make a file invisible to the user by prepending its name with a period character. Adding this character signals to the Finder and other display-related interfaces that they should treat the file as invisible under normal conditions. You should use this capability sparingly, though, and only in very specific cases. For example, the process for localizing a custom directory name involves placing hidden files with the localized names at the top-level of the directory. You should never use this technique to hide user documents or other data your app creates.

  • 在macOS中,通过在名称前加上句点字符,可以使用户不可见文件。 将此字符信号添加到Finder和其他与显示相关的接口,他们应该在正常条件下将文件视为不可见。 但是,您应该谨慎使用此功能,并且仅在非常特殊的情况下使用。 例如,本地化自定义目录名称的过程涉及将具有本地化名称的隐藏文件放在目录的顶层。 您永远不应该使用此技术来隐藏用户文档或您的应用创建的其他数据。

Even if you mark a file as invisible, there are still ways for the user to see it. Users can always view the true file system contents using the Terminal app. Unlike the Finder, the command line in the Terminal window displays the actual names of items in the file system and not their display names or localized names. You can also show hidden files in the Open and Save panels (using the setShowsHiddenFiles: method) in cases where you want the user to be able to select them for viewing or editing.

  • 即使您将文件标记为不可见,用户仍然可以看到它。 用户始终可以使用终端应用查看真实的文件系统内容。 与Finder不同,终端窗口中的命令行显示文件系统中项目的实际名称,而不显示其显示名称或本地化名称。 如果希望用户能够选择它们进行查看或编辑,还可以在“打开”和“保存”面板中显示隐藏文件(使用setShowsHiddenFiles:方法)。

Regardless of whether a file contains a leading period, your app’s code can always see hidden files. Methods that enumerate the contents of directories generally include hidden files in the enumeration. The only exceptions to this rule is the meta directories . and .. that represent the current and parent directories. Therefore, any code that enumerates the contents of a directory should be prepared to handle hidden files and deal with them appropriately, usually by just ignoring them.

  • 无论文件是否包含前导期,您的应用程序代码始终可以看到隐藏文件。 枚举目录内容的方法通常包括枚举中的隐藏文件。 此规则的唯一例外是元目录。 和..代表当前和父目录。 因此,任何枚举目录内容的代码都应该准备好处理隐藏文件并适当地处理它们,通常只是忽略它们。

相关文章

网友评论

      本文标题:Managing Files and Directories

      本文链接:https://www.haomeiwen.com/subject/reyltqtx.html