iOS文件path上的/ private前缀表示什么?

当我的应用程序在iPhone上运行,但在模拟器上运行时,我有一个错误。 我正在使用主目录path的长度来提取/ Documents中文件的相对path。 不幸的是,这并不总是在iPhone上正常工作,因为前缀“/ private”被添加到主path。 但是,无论是否有前缀,都会引用同一个文件。 以下代码演示了这种不一致。 “/ private”的用途是什么?什么时候由iOS提供?

- (IBAction)testHomepath:(id)sender { NSFileManager *fmgr = [NSFileManager defaultManager]; NSString *homePath = [NSString stringWithFormat:@"%@/Documents",NSHomeDirectory()]; NSString *dirPath = [homePath stringByAppendingPathComponent:@"TempDir"]; NSURL *dirURL = [NSURL fileURLWithPath:dirPath]; NSString *filePath = [dirPath stringByAppendingPathComponent:@"test.jpg"]; [fmgr createDirectoryAtPath:dirPath withIntermediateDirectories:NO attributes:nil error:nil]; [fmgr createFileAtPath:filePath contents:nil attributes:nil]; NSArray *keys = [[NSArray alloc] initWithObjects:NSURLNameKey,nil]; NSArray *files = [fmgr contentsOfDirectoryAtURL:dirURL includingPropertiesForKeys:keys options:0 error:nil]; NSURL *f1 = (files.count>0)? [files objectAtIndex:0] : 0; NSURL *f2 = (files.count>1)? [files objectAtIndex:1] : 0; bool b0 = [fmgr fileExistsAtPath:filePath]; bool b1 = [fmgr fileExistsAtPath:f1.path]; bool b2 = [fmgr fileExistsAtPath:f2.path]; NSLog(@"File exists=%d at path:%@",b0,filePath); NSLog(@"File exists=%d at path:%@",b1,f1.path); NSLog(@"File exists=%d at path:%@",b2,f2.path); } 

以下内容在iPhone上运行时写入日志。 我手动间隔输出显示行1和2之间的区别。

 2013-02-20 16:31:26.615 Test1[4059:907] File exists=1 at path: /var/mobile/Applications/558B5D82-ACEB-457D-8A70-E6E00DB3A484/Documents/TempDir/test.jpg 2013-02-20 16:31:26.622 Test1[4059:907] File exists=1 at path:/private/var/mobile/Applications/558B5D82-ACEB-457D-8A70-E6E00DB3A484/Documents/TempDir/test.jpg 2013-02-20 16:31:26.628 Test1[4059:907] File exists=0 at path:(null) 

在模拟器上运行时(不包括“/ private”),将以下内容写入日志:

 2013-02-20 16:50:38.730 Test1[7224:c07] File exists=1 at path:/Users/kenm/Library/Application Support/iPhone Simulator/6.1/Applications/C6FDE177-958C-4BF5-8770-A4D3FBD281F1/Documents/TempDir/test.jpg 2013-02-20 16:50:38.732 Test1[7224:c07] File exists=1 at path:/Users/kenm/Library/Application Support/iPhone Simulator/6.1/Applications/C6FDE177-958C-4BF5-8770-A4D3FBD281F1/Documents/TempDir/.DS_Store 2013-02-20 16:50:38.733 Test1[7224:c07] File exists=1 at path:/Users/kenm/Library/Application Support/iPhone Simulator/6.1/Applications/C6FDE177-958C-4BF5-8770-A4D3FBD281F1/Documents/TempDir/test.jpg 

我试过这个从debugging器,发现URLByResolvingSymlinksInPath “修复” /private/添加。

 (lldb) p (NSURL *)[NSURL fileURLWithPath:@"/private/var" isDirectory:YES] (NSURL *) $1 = 0x1fd9fc20 @"file://localhost/private/var/" (lldb) po [$1 URLByResolvingSymlinksInPath] $2 = 0x1fda0190 file://localhost/var/ (lldb) p (NSURL *)[NSURL fileURLWithPath:@"/var" isDirectory:YES] (NSURL *) $7 = 0x1fd9fee0 @"file://localhost/var/" (lldb) po [$7 URLByResolvingSymlinksInPath] $8 = 0x1fda2f50 file://localhost/var/ 

正如你所看到的, file://localhost/var就是我们真正想要的。

因此,很显然/private/var/private/var的一个符号链接。 不过,@凯文 – 巴拉德指出这是不正确的。 我确认他是正确的,而/var/private/var (sigh)的符号链接

 (lldb) p (NSDictionary *)[[NSFileManager defaultManager] attributesOfItemAtPath:@"/var" error:nil] (NSDictionary *) $3 = 0x1fda11b0 13 key/value pairs (lldb) po $3 $3 = 0x1fda11b0 { ... NSFileType = NSFileTypeSymbolicLink; } (lldb) p (NSDictionary *)[[NSFileManager defaultManager] attributesOfItemAtPath:@"/private/var" error:nil] (NSDictionary *) $5 = 0x1fda4820 14 key/value pairs (lldb) po $5 $5 = 0x1fda4820 { ... NSFileType = NSFileTypeDirectory; } 

因此, URLByResolvingSymlinksInPath在这里做一些有趣的事情,但现在我们知道了。 对于这个特定的问题, URLByResolvingSymlinksInPath仍然听起来像是一个很好的解决scheme,适用于模拟器和设备,并且如果有什么变化,将来会继续工作。

要真正回答你的问题:

我相信/private是在发布OS X时添加的前缀(我不认为它在NeXTStep中,但已经有几十年了 )。 它似乎存在的房屋etcvartmp (和,奇怪, tftpboot ;我不知道我的PBG4可以做到这一点),也许这样用户不知道这个愚蠢的文件夹etc是什么,并试图删除它。

在设备上,苹果决定将用户数据存储在/private/var/mobile (用户名是“mobile”)。 我不确定他们为什么不select/Users/mobile或者just /mobile ,但是没有比“普通”Unix上的/var/mobile更重要。

在模拟器上,您的用户帐户无法写入/var (出于很好的原因)。 用户数据存储在~/Library/Application Support/iPhone Simulator 。 有一次,他们开始为不同的模拟器版本使用不同的目录。

Swift 3中, URL具有standardizedFileUrl属性,它将删除任何符号链接并parsingpath中的相关部分,如./

在编写文档的时候 ,这个文档是相当无用的,但是看起来它和NSURLstandardized属性是同等的。

/var只是/private/var一个符号链接。 所以第一条path是你试图访问的逻辑path。 第二个是扩展了符号链接的相同path。