当前位置:  开发笔记 > IOS > 正文

如何找到文件名的正确大小写?

如何解决《如何找到文件名的正确大小写?》经验,为你挑选了2个好方法。

这是在Mac上:

如果我有两个文件名/ foo/foo和/ foo/FOO,它们可能引用相同的文件,或者可能是不同的文件,具体取决于文件系统.我怎么弄清楚它们是否都指向同一个文件?如果是,我如何获得文件名的正确表示?

我的问题是由链接引起的.链接可能指向/ foo/FOO,但实际目录名为/ foo/foo.

是否有任何函数将跟随链接并给我链接文件的完整路径?[NSFileManager pathContentOfSymbolicLinkAtPath]给出可能处于不正确情况的相对路径.

最终我要做的是缓存文件的信息.但是如果我有两个不同的路径用于同一个文件,我的缓存可能会失去同步.

谢谢



1> TALlama..:

你的问题确实有几个不同的部分.通过我的阅读,你想要:

1一种判断两个不同路径是否是同一磁盘文件的方法

2磁盘上文件的规范名称,带有正确的外壳

还有第三个问题与显示名称有关,因为在OS X中,文件可以本地化其名称,并且对于不同的语言环境显示不同.所以让我们补充一下

3获取显示名称的方法,因为我们可能希望根据用户查看文件系统的方式来缓存内容,而不是文件系统在终端中的显示方式.

我们可以用@ boaz-stuller指出的FSRef技巧来解决1.或者这里有一些代码使用更高级别的Cocoa调用来完成它,这为我们节省了一些内存(因为我们可以让它NSAutoreleasePool为我们做):

long getInode(NSString* path) {
    NSFileManager* fm = [NSFileManager defaultManager];
    NSError* error;
    NSDictionary* info = [fm attributesOfItemAtPath:path error:&error];
    NSNumber* inode = [info objectForKey:NSFileSystemFileNumber];
    return [inode longValue];
}

但要解决2,我们必须使用FSRefs来找出文件的规范框:

NSString* getActualPath(NSString* path) {
    FSRef ref;
    OSStatus sts;
    UInt8* actualPath;

    //first get an FSRef for the path
    sts = FSPathMakeRef((const UInt8 *)[path UTF8String], &ref, NULL);
    if (sts) return [NSString stringWithFormat:@"Error #%d making ref.", sts];

    //then get a path from the FSRef
    actualPath = malloc(sizeof(UInt8)*MAX_PATH_LENGTH);
    sts = FSRefMakePath(&ref, actualPath, MAX_PATH_LENGTH);
    if (sts) return [NSString stringWithFormat:@"Error #%d making path.", sts];

    return [NSString stringWithUTF8String:(const char*)actualPath];
}

这一点都不错,但是当我们用Cocoa方法解决3时我们仍然很高兴:

NSString* getDisplayPath(NSString* path) {
    NSFileManager* fm = [NSFileManager defaultManager];
    NSString* mine = [fm displayNameAtPath:path];
    NSString* parentPath = [path stringByDeletingLastPathComponent];
    NSString* parents = [@"/" isEqualToString:parentPath]
        ? @""
        : getDisplayPath(parentPath);
    return [NSString stringWithFormat:@"%@/%@", parents, mine];
}

最后,我们可以添加一些驱动程序代码并将它们整合到一个CoreFoundation命令行工具中(我必须添加AppKit框架才能进行编译).

NSString* fileInfoString(NSString* path) {
    long inode = getInode(path);
    return [NSString stringWithFormat:
        @"\t%@  [inode #%d]\n\t\tis actually %@\n\t\tand displays as %@",
        path,
        inode,
        getActualPath(path),
        getDisplayPath(path)];
}

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    if (argc < 2) {
        NSLog(@"Usage: %s  []", argv[0]);
        return -1;
    }

    NSString* path1 = [NSString stringWithCString:argv[1]];
    NSString* path2 = argc > 2
        ? [NSString stringWithCString:argv[1]]
        : [path1 uppercaseString];

    long inode1 = getInode(path1);
    long inode2 = getInode(path2);

    NSString* prefix = [NSString stringWithFormat:
        @"Comparing Files:\n%@\n%@", 
        fileInfoString(path1), 
        fileInfoString(path2)];

    int retval = 0;
    if (inode1 == inode2) {
        NSLog(@"%@\nSame file.", prefix);
    } else {
        NSLog(@"%@\nDifferent files.", prefix);
        retval = 1;
    }

    [pool drain];
    return retval;
}

现在,我们可以将它们放在一起并运行它:

 $ checkpath /users/tal
 2008-12-15 23:59:10.605 checkpath[22375:10b] Comparing Files:
    /users/tal  [inode #1061692]
        is actually /Users/tal
        and displays as /Users/tal
    /USERS/TAL  [inode #1061692]
        is actually /Users/tal
        and displays as /Users/tal
 Same file.



2> Boaz Stuller..:

FSPathMakeRef()在两个路径上使用,然后使用FSCompareFSRefs()它们来查看它们是否是同一个文件/文件夹.然后,您可以使用FSRefMakePath()获取规范表示,但如果您向用户显示文件名,则应使用NSFileManager's- displayNameAtPath:方法,因为它可以正确处理本地化和显示/隐藏扩展.

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有