【问题标题】:iPhone unix file accessiPhone unix 文件访问
【发布时间】:2012-01-19 09:45:58
【问题描述】:

当我使用时:

int fd = open(fileNameWitPath, O_CREAT | O_RDWR);

在设备模拟器中一切正常。 但是物理设备返回 fd = -1errno = 0x0d (13),权限被拒绝。

目标路径是应用程序沙箱文档或 tmp 路径。

这是否可以在 iPhone 上通过 Unix 功能在应用程序私有区域中读取和写入文件而无需越狱?

【问题讨论】:

  • 您可以访问应用程序沙箱中的文件(例如 Documents 文件夹)。你怎么得到fileNameWitPath?要获取您需要执行的 Documents 目录:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docPath = [paths objectAtIndex:0]; 用于临时目录:NSTemporaryDirectory() 是一个 NSString,其路径为 tmp
  • "你怎么得到..." : NSArray *dp = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *path = [dp objectAtIndex:0];
  • 请重新阅读我的答案,我已经重写了。代码现在可以工作了。

标签: iphone file permissions


【解决方案1】:

它应该可以正常工作,但您必须记住 iOS 模拟器使用的文件系统与真实设备不同。事实上,您只能从包中读取文件,而不是 WRITE,并且您尝试以读\写权限打开。请检查 fileNameWitPath

的值

获取文档目录的正确方法是:

NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

你应该使用

NSFileManager *fileManager = [NSFileManager defaultManager]; 
[fileManager createFileAtPath: contents: attributes:]

而不是

int fd = open(fileNameWitPath, O_CREAT | O_RDWR);

【讨论】:

  • 我认为这是“你必须使用”而不是“你也可以使用”的情况:P
  • 经过 2 天的文件访问斗争后,我的结论是:设备下的 posix io​​ 功能,在“.../Documents/”文件夹中,工作不好。文件已创建,但 open() 或 creat() 总是返回描述符 -1 和 errno 0x0d。 iPhone 对我来说很奇怪:) 在 symbian、android 等下工作,但在 iOS 下不工作。现在我使用 fileManager 就可以了。
【解决方案2】:

Skippy 关于缺少第三个参数的评论是正确的问题。

如果没有第三个参数,open(...) 将在第一次运行,并在后续运行中以 -1 和 EACCES 失败,因为应用程序第一次创建了文件,但不再具有访问该文件的权限。 (如果您在设备上重新编译和测试,并且看到错误,那是因为您需要删除应用程序,该应用程序删除了错误的权限文件。)

【讨论】:

    【解决方案3】:

    *完全重写答案*

    以下代码有效:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
    
        NSArray *dp = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *path = [dp objectAtIndex:0];
        NSString *fileNameWithPath = [NSString stringWithFormat:@"%@/%@",path,@"fileName.txt"];
        int fd = open([fileNameWithPath UTF8String], O_CREAT | O_RDWR);
    
        NSLog(@"Open %@ for writing returned %d",fileNameWithPath,fd);
    
        return YES;
    }
    

    调试输出:

    Re-enabling shared library breakpoint 1
    (gdb) n
    30      NSLog(@"Open %@ for writing returned %d",fileNameWithPath,fd);
    (gdb) n
    2012-01-20 11:01:23.161 FOpen[6535:707] Open /var/mobile/Applications/AF7EA358-E4AA-491F-AEA1-83080F2749E5/Documents/fileName.txt for writing returned 6
    32      return YES;
    

    关键是你必须通过 c 函数 'open' 一个 c 风格的字符串,例如[fileNameWithPath UTF8String]。如果您使用的是 ARC,您可能需要做更多的工作才能让编译器满意,不过我无法确认。

    【讨论】:

    • 所以我用同样的方法来获取路径,但是 open() or creat() 的结果总是-1,errno 0x0d。 tmp 路径的结果相同: NSString *path = NSTemporaryDirectory();还有一件事 - 在 XCode Organizer、Applications (for my device) 和“沙箱中的数据文件”中 - 该文件存在,但长度 = 0B。
    • 设备上的路径,我在其中探测写入文件:/var/mobile/Applications/7FF29BC7-B6D1-41CF-8621-CC6DFEEEEF045/Documents
    • "...文件存在,但长度 = 0B..." 这意味着 open() 创建文件,但不返回描述符,表示“访问被拒绝”。我完全不明白。
    • 感谢您的信息。我将在一个虚拟应用程序中快速浏览一下自己。
    • 我得到相同的输出:2012-01-20 10:45:41.830 FOpen[6513:707] Open /var/mobile/Applications/AF7EA358-E4AA-491F-AEA1-83080F2749E5/Documents/fileName.txt for writing returned -1 我现在会接受行为已经改变,所以我可能会接受 Oded 的回答。
    【解决方案4】:

    我在写:

    int fd = open(fileNameWithPath, O_CREAT | O_RDWR);
    

    但是“在设置 'O_CREAT' 时调用 'open' 需要第三个参数”。 代码行必须是(对于 RW 权限):

     int fd = open(fileNameWithPath, O_CREAT | O_RDWR, 0x0666);
    

    这很好用。

    [编辑] 我在写:

    int fd = open(fileNameWithPath, O_CREAT | O_RDWR, 0x0666);
    

    这是错误,umask 必须是 666,但必须是八进制,而不是十六进制:

    int fd = open(fileNameWithPath, O_CREAT | O_RDWR, 00666);
    

    【讨论】:

      猜你喜欢
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-09
      • 2020-06-18
      • 2014-04-10
      相关资源
      最近更新 更多