我发布这个问题是因为我有一个完整的答案,这篇文章是针对另一篇文章写的,当时我发现它不适用于原版,但我觉得它太浪费了.因此,我也将其作为社区维基,以便其他人可以充实问答.如果您觉得答案有用,请投票提出问题 - 作为社区维基我不应该为此投票获得积分,但它会帮助其他人找到它
如何获取iPhone上允许写入文件的路径?您可以(误导性地)在模拟器上随意写任何地方,但在iPhone上,您只能写入特定位置.
有三种可写路径需要考虑 - 第一种是文档,您可以存储要保留的内容并通过iTunes向用户提供(截至3.2):
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0];
其次,与Documents目录非常相似,还有Library文件夹,您可以在其中存储您想要保留的配置文件和可写数据库,但您不希望用户能够通过iTunes进行操作:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *libraryDirectory = [paths objectAtIndex:0];
请注意,即使用户无法使用3.2之前的设备(iPad)查看iTunes中的文件,NSLibraryDirectory常量自iPhoneOS 2.0起已可用,因此可用于针对3.0的构建(如果您仍在进行,甚至更早)那).除非您将应用程序标记为允许用户修改文档,否则用户将无法看到任何内容,因此,如果您今天使用文档,只要您在更新位置时更改用户文档的支持就可以了.
最后有一个缓存目录,您可以在其中放置您不关心长期存在的图像(手机可能会在某些时候删除它们):
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); NSString *cachePath = [paths objectAtIndex:0]; BOOL isDir = NO; NSError *error; if (! [[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) { [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:NO attributes:nil error:&error]; }
请注意,您必须在那里实际创建Caches目录,因此在编写时您必须每次都检查并创建!有点痛,但就是这样.
然后当你有一个可写路径时,你只需要在其上附加一个文件名,如下所示:
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"SomeDirectory/SomeFile.txt"];
要么
NSString *filePath = [cachePath stringByAppendingPathComponent:@"SomeTmpFile.png"];
使用该路径进行读写.
请注意,您可以在任何可写路径中创建子目录,上面的示例字符串之一正在使用(假设已创建一个).
如果您尝试将图像写入照片库,则无法使用文件系统调用来执行此操作 - 相反,您必须在内存中使用UIImage,并使用UIImageWriteToSavedPhotosAlbum()
UIKit定义的函数调用.您无法控制目标格式或压缩级别,也无法以这种方式附加任何EXIF.
感谢上面的Kendall&Dave,我认为这个修正案有助于提出.当用于一次性调试代码时,我使用Mike Ash的NSBlog中的这个技巧来消除临时变量isDir&error,最小化行数并使详细程度几乎可以忍受:
NSFileHandle *dumpFileHandle = nil; #ifdef DEBUG NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&(BOOL){0}]) [[NSFileManager defaultManager] createDirectoryAtPath:cachePath withIntermediateDirectories:YES attributes:nil error:&(NSError*){nil}]; NSString *dumpPath = [cachePath stringByAppendingPathComponent:@"dump.txt"]; [[NSFileManager defaultManager] createFileAtPath:dumpPath contents:nil attributes:nil]; [(dumpFileHandle = [NSFileHandle fileHandleForWritingAtPath:dumpPath]) truncateFileAtOffset:0]; #endif if (dumpFileHandle) [dumpFileHandle writeData:blah];