将NSData写入文件的最简单方法

70
NSData *data;
data = [self fillInSomeStrangeBytes];

我的问题现在是如何以最简单的方式将data写入文件。

(我已经有一个NSURL file://localhost/Users/Coding/Library/Application%20Support/App/file.strangebytes

5个回答

101

NSData有一个叫做writeToURL:atomically:的方法,它恰好可以实现你想要的功能。请查看NSData的文档以了解如何使用它。


1
这个方法中,NSData对象的来源是否重要?在这个问题中,我从一个URL下载了一个.sqlite数据库并将其存储到了一个NSData对象中,但似乎没有正确保存。文件已经被写入,但当我尝试访问它时(通过我的应用程序或第三方查看器),它告诉我它不是有效的SQLite数据库。writeToURL:atomically:只适用于保存NSStrings或类似的内容吗? - GeneralMike
1
NSData是任何二进制数据的包装器。原始来源并不重要。根据您的问题,我建议使用NSURLConnection(或类似AFNetworking的库)而不是initWithContentsOfURL:。对于小型下载,NSData可能很好,但它不提供对下载的任何控制。当出现问题时,这使得诊断问题变得困难。 - Alex

38

请注意,将NSData写入文件是可能会阻塞主线程的IO操作,特别是当数据对象很大时。

因此建议在后台线程上执行此操作,最简单的方法是使用GCD,如下所示:

// Use GCD's background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    // Generate the file path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"yourfilename.dat"];

     // Save it into file system
    [data writeToFile:dataPath atomically:YES];
});

1
如何检索它? - user3600801

31

2
+1 for NSURL。当你指向一个文件时,NSURL比NSString更好。苹果公司总是建议使用NSURL来处理文件路径,而不是NSString。 :) - user142019
9
根据文档,“writeToURL”和“writeToFile:atomically:”没有区别,除了第一个参数的类型不同,因为目前只支持“file://” URL。 - Ronnie Liew
这个方法中,NSData对象的来源是否重要?在这个问题中,我将从URL下载的.sqlite数据库保存到了一个NSData对象中,但似乎没有正确地保存它。文件已经被写入,但是当我尝试访问它(无论是通过我的应用程序还是第三方查看器)时,它告诉我它不是有效的SQLite数据库。writeToURL:atomically:只适用于保存NSString或类似的东西吗? - GeneralMike

4
你还可以使用 writeToFile:options:error:writeToURL:options:error: 来保存 NSData,如果由于任何原因保存失败,则可以报告错误代码。例如:
NSError *error;

NSURL *folder = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:true error:&error];
if (!folder) {
    NSLog(@"%s: %@", __FUNCTION__, error);        // handle error however you would like
    return;
}

NSURL *fileURL = [folder URLByAppendingPathComponent:filename];
BOOL success = [data writeToURL:fileURL options:NSDataWritingAtomic error:&error];
if (!success) {
    NSLog(@"%s: %@", __FUNCTION__, error);        // handle error however you would like
    return;
}

0

如果您想手动执行此操作而不是编码,最简单的方法是仅使用鼠标:

  1. 在NSdata被满足的一行后面设置断点。

enter image description here

  1. 将鼠标悬停在NSData变量上,单击眼睛按钮,然后导出。

  2. 之后选择存储细节(文件名/扩展名/位置)。

enter image description here

4. 点击“保存”即可完成!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接