0

我有这段代码可以从文件夹中获取所有文件:

- (NSMutableArray*) allFilesAtPath:(NSString *)startPath
{
    NSMutableArray* listing = [NSMutableArray array];
    NSArray* fileNames = [self contentsOfDirectoryAtPath:startPath error:nil];
    if (!fileNames) return listing;

    for (NSString* file in fileNames) {
        NSString* absPath = [startPath stringByAppendingPathComponent:file];

        BOOL isDir = NO;
        if ([self fileExistsAtPath:absPath isDirectory:&isDir]) {

            [listing addObject:absPath];
            if (isDir) [listing addObjectsFromArray:[self allFilesAtPath:absPath]];
        }
    }
    return listing;
}

在一个测试文件夹中,我有一个名为yahoéo.jpg
When NSLogged 的​​文件,它显示为yahoe\U0301o.jpg

当然,这对于文件名中没有这种强调字符的任何其他文件都适用。

因此,当我尝试使用以下命令从数组中删除它时:

[theFilesArray removeObject:fileName];

fileName 是yahoéo.jpg
它没有被删除,因为它没有在数组中找到。

为什么我有这样的字符替换。我在文档中找不到任何关于此的内容。哪些角色应该受到相同的待遇?我怎么会知道呢?

最重要的是,我该如何获取é文件名数组中的字符?

编辑

fileNameremoveObject 方法中使用的变量是通过从 PList 文件中获取字符串并将其提供给以下方法来构造的:

+ (NSString*) fileNameWithString:(NSString*)str
{
    NSString* fileName = str;

    NSCharacterSet* charactersToRemove = [NSCharacterSet characterSetWithCharactersInString:@".:/\\"];
    fileName = [[fileName componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@"#"];

    fileName = [fileName stringByAppendingString:@".jpg"];

    return fileName;
}
4

1 回答 1

2

an的NSLog输出以转义形式NSArray显示所有非 ASCII 字符。\Unnnn但这只是NSLog打印它的方式,所以这不应该是问题。

我认为这是“预组合”与“分解”字符的问题。HFS 文件系统在文件名中使用分解字符,因此é存储为两个 Unicode 字符:

U+0065 + U+0301  = "e" + COMBINING ACUTE ACCENT

(并且 NSLog 将其打印为e\U0301)。

这不同于单个 Unicode 字符(预先组合的形式)

U+00E9 = "é" 

因此,如果字符串yahoéo.jpg的字符以预先组合的形式存储,则不会在数组中找到该字符串。

如果这确实是问题所在,您可以通过precomposedStringWithCanonicalMapping使用decomposedStringWithCanonicalMapping.NSString

评论:

  • 字符串的预组合和分解版本都将以相同的方式显示(例如é)。
  • compare:方法NSString将字符串的两个版本视为相等(除非您使用NSLiteralSearch选项调用它)。
  • isEqual:方法NSString将字符串的两个版本视为不同的,用于removeObject:查找要删除的对象。
于 2013-07-26T22:30:48.350 回答