NSFileManager - 在启动时复制文件

发布于 2024-09-01 19:49:46 字数 1205 浏览 6 评论 0原文

我需要从应用程序的资源文件夹中复制一些示例文件,并将它们放在应用程序的文档文件夹中。我想出了附加的代码,它编译得很好,但不起作用。我引用的所有目录都存在。我不太确定我做错了什么,有人可以指出我正确的方向吗?

NSFileManager*manager = [NSFileManager defaultManager];

NSString*dirToCopyTo = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

NSString*path = [[NSBundle mainBundle] resourcePath];

NSString*dirToCopyFrom = [path stringByAppendingPathComponent:@"Samples"];


NSError*error;

NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyFrom error:nil];

for (NSString *file in files)
{
        [manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:dirToCopyTo error:&error];

        if (error)
        {
            NSLog(@"%@",[error localizedDescription]);
    }
}

编辑:我刚刚按照应有的方式编辑了代码。然而现在还有另一个问题:

2010-05-15 13:31:31.787 写它 移动[4587:207] DAMutableDictionary.h 2010-05-15 13:31:31.795 写它 移动[4587:207]文件管理器 错误:操作无法进行 完全的。文件存在

编辑:我通过告诉 NSFileManager 复制文件的目的地的名称解决了这个问题。

        [manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:[dirToCopyTo stringByAppendingPathComponent:file] error:&error];

I need to copy a few sample files from my app's resource folder and place them in my app's document folder. I came up with the attached code, it compiles fine but it doesn't work. All the directories I refer to do exist. I'm not quite sure what I am doing wrong, could someone point me in the right direction please?

NSFileManager*manager = [NSFileManager defaultManager];

NSString*dirToCopyTo = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

NSString*path = [[NSBundle mainBundle] resourcePath];

NSString*dirToCopyFrom = [path stringByAppendingPathComponent:@"Samples"];


NSError*error;

NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyFrom error:nil];

for (NSString *file in files)
{
        [manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:dirToCopyTo error:&error];

        if (error)
        {
            NSLog(@"%@",[error localizedDescription]);
    }
}

EDIT: I just edited the code the way it should be. Now however there's another problem:

2010-05-15 13:31:31.787 WriteIt
Mobile[4587:207] DAMutableDictionary.h
2010-05-15 13:31:31.795 WriteIt
Mobile[4587:207] FileManager
Error:Operation could not be
completed. File exists

EDIT : I have fixed the issue by telling NSFileManager the names of the copied files's destinations.

        [manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:[dirToCopyTo stringByAppendingPathComponent:file] error:&error];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

老街孤人 2024-09-08 19:49:46

我认为问题出在这一行:

NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyTo error:nil];

您正在目标目录而不是源目录中列出文件。将其更改为:

NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyFrom error:nil];

你应该没问题。

I think the problem is in this line:

NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyTo error:nil];

You are listing files in a destination directory instead of the source. Change it to something like:

NSArray*files = [manager contentsOfDirectoryAtPath:dirToCopyFrom error:nil];

And you should be fine.

记忆で 2024-09-08 19:49:46

我认为问题是您正在读取要从 dirToCopyTo 复制的文件,我认为您的意思是 dirToCopyFrom

还要获取您应该使用的文档目录 NSDocumentDirectory- (NSArray *)URLsForDirectory:(NSSearchPathDirectory)Domains 中的目录:(NSSearchPathDomainMask)domainMask

I think the problem is that yo are reading the files to copy from dirToCopyTo and I think you meant dirToCopyFrom

Also to get the documents directory you should be using NSDocumentDirectory with - (NSArray *)URLsForDirectory:(NSSearchPathDirectory)directory inDomains:(NSSearchPathDomainMask)domainMask

妖妓 2024-09-08 19:49:46

请注意,必须避免启动时的冗长操作:

  1. 不好的用户体验(延迟和裁剪行为)
  2. iOS 中的 Watchdog 可能会杀死您的应用程序,就像它被卡住一样。

因此,在辅助线程中执行复制(或操作......或任何使用不同执行路径的内容)。

如果您需要数据来填充 UI,则会出现另一个问题:在这种情况下:

  • 禁用 UI 元素
  • 启动异步/线程操作
  • 在复制的完成回调中(通过通知、协议..或其他方式)
    通知UI界面可以开始获取数据了。

例如,我们复制一个 ZIP 文件并将其解压缩,但这需要一些时间,因此我们必须将其放入计时器程序中,完成后将触发 UI。

如果您需要示例,请告诉我。

PS:
使用 ZIP 文件进行复制的效率更高,因为:

  1. 仅调用文件系统
  2. 要复制的字节少得多

坏消息:您必须使用例程来解压缩 zip 文件,但您可以在网络上找到它们。

解压缩 Zip 文件应该更有效,因为这些调用是直接用 C 编写的,而不是用 Cocoa 编写的,开销很大。

Please note that lengthy operation on startup must be avoided:

  1. Not a good User Experience (delay and croppy behavior)
  2. Watchdog in iOS can kill your app as if it were stuck.

So perform copy in a secondary thread (or operation... or whatever uses a different execution path).

Another problem will arise if You need data to populate your UI: in that case:

  • Disable UI elements
  • Start an async / threaded operation
  • In the completion call back of copying (via a notification, a protocol.. or other means)
    notify to the UI interface it can start fetching data.

For example we copy a ZIP file and decompress it, but it takes some time so we had to put it in a timer procedure that will trigger UI when done.

If You need an example, ket me know.

PS:
Copying using ZIP file is MORE efficient as:

  1. Only call to file system
  2. Far less bytes to copy

The bad news: you must use a routine do decompress zip file, but you can find them on the web.

Decompressing Zip files should be more efficient as these calls are written in straight C, and not in Cocoa with all the overhead.

姜生凉生 2024-09-08 19:49:46
 [manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:dirToCopyTo error:&error];

目标路径是您希望副本具有的路径,包括其文件名。您无法将路径传递到期望 NSFileManager 填充源文件名称的目录;它不会这样做。

文档 表示目标路径不得描述任何存在的内容:

... dstPath 在操作之前不得存在。

在您的情况下,它是目标目录的路径,因此它确实存在,这就是复制失败的原因。

您需要通过向其附加所需的文件名来使其成为目标文件的路径。那么它就不会存在(如果之前没有复制的话),所以复制会成功。

    [manager copyItemAtPath:[dirToCopyFrom stringByAppendingPathComponent:file] toPath:dirToCopyTo error:&error];

The destination path is the path you want the copy to have, including its filename. You cannot pass the path to a directory expecting NSFileManager to fill in the name of the source file; it will not do this.

The documentation says that the destination path must not describe anything that exists:

… dstPath must not exist prior to the operation.

In your case, it's the path to the destination directory, so it does exist, which is why the copy fails.

You need to make it a path to the destination file by appending the desired filename to it. Then it will not exist (if not previously copied), so the copy will succeed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文