【问题标题】:How to get full path (including mount directory) for file path?如何获取文件路径的完整路径(包括挂载目录)?
【发布时间】:2013-11-12 02:23:10
【问题描述】:

我正在为 Coda 开发一个插件,但在尝试将文件路径与 sqlite 行进行比较时遇到了一个奇怪的问题。

基本上,NSOpenPanel 返回一个 NSURL,它返回如下路径:

/Users/michael/Documents/xcode stuff/hM github/Plugin/filename

Coda 返回当前文件路径如下:

/Volumes/Macintosh HD/Users/michael/Documents/xcode stuff/hM github/Plugin/filename

在给定来自 Coda 的路径的情况下,我需要能够检索与此文件相关联的 sqlite 行(最初是在用户通过 NSOpenPanel 选择文件时创建的)。

有没有办法获取文件的实际完整路径,包括卷信息? 或者,是否有更好的方法来存储对可以轻松检索的文件的引用,而不管给定路径如何?

更新

我已经意识到 Coda 会修改保存的文件,以至于您不能依赖文件的 inode 编号来保持一致,因此 trojanfoe 的答案对我不起作用。

【问题讨论】:

    标签: objective-c macos


    【解决方案1】:

    无论文件如何指定(绝对、相对或包括挂载),唯一标识文件的更好方法是使用文件的设备和 inode 编号,它们在系统中是唯一的:

    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/stat.h>
    
    static void get_file_details(const char *filename) {
        struct stat statbuf;
        if (stat(filename, &statbuf) == 0) {
            printf("%s = %016llx%016llx\n", filename, (uint64_t)statbuf.st_dev, (uint64_t)statbuf.st_ino);
        } else {
            fprintf(stderr, "Failed to stat '%s': %s\n", filename, strerror(errno));
        }
    }
    
    int main(int argc, const char **argv) {
        for (int i = 1; i < argc; i++)
            get_file_details(argv[i]);
        return 0;
    }
    
    $ clang -o stattest stattest.c
    $ ./stattest stat*
    stattest = 00000000010000010000000001b1d48a
    stattest.c = 00000000010000010000000001b1d43b
    

    您需要决定如何格式化设备/inode 组合,但上述格式在大多数情况下应该可以正常工作。

    【讨论】:

    • 谢谢,这正是我想要的。我能够通过 NSFileManager 提取设备和 inode #'s。
    • 不!我被 Coda 挫败了。显然,但是 Coda 决定保存文件会更改 inode 编号,从而使此方法无用。
    • @mjvotaw 啊,这很痛苦。我想你必须找到一些以一致的方式获取绝对文件名的方法(即将 Coda 的文件名转换为一致的格式)。
    【解决方案2】:

    查看以下内容:

    miranda-6:~ jeremyp$ ls -l /Volumes
    total 8
    drwxr-xr-x   1 jeremyp  staff  8192 23 Oct 06:54 BOOTCAMP
    drwxrwxr-x@ 20 jeremyp  staff   748 23 Oct 11:22 G-DRIVE
    lrwxr-xr-x   1 root     admin     1 28 Oct 07:25 Macintosh HD -> /
    drwxrwxrwx   0 root     wheel     0  1 Nov 16:28 MobileBackups
    miranda-6:~ jeremyp$ 
    

    /Volumes/Macintosh HD 是指向/ 的符号链接。

    所以你应该做的 (IMO) 是遍历 /Volumes 中的项目,直到找到指向 / 的符号链接然后每当你从 Coda 获得以 /Volumes/&lt;the item linked to / &gt; 开头的文件路径时, 你在数据库中搜索它之前把它去掉。

    您可以使用NSFileManager attributesOfItemAtPath:error: 找出您是否有符号链接,使用NSFileManager -destinationOfSymbolicLinkAtPath:error: 找出符号链接的位置。

    【讨论】:

    • 你说的完全正确,我是在倒着看问题。解决方案其实很简单: NSURL * url = [NSURL fileURLWithPath:somePath]; url = [NSURL URLWithString:[url absoluteString]]; NSString * newPath = [[url URLByResolvingSymlinksInPath] 路径];
    猜你喜欢
    • 2022-01-03
    • 2010-10-15
    • 2011-03-26
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多