我有这段代码可以从文件夹中获取所有文件:
- (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
的文件
当 NSLogged 时,显示为 yahoe\U0301o.jpg
当然,对于文件名中没有这种强调字符的任何其他文件,这也适用。
因此,当我尝试使用以下命令将其从数组中删除时:
[theFilesArray removeObject:fileName];
文件名是 yahoéo.jpg
它没有被删除,因为在数组中找不到它。
为什么我会有这样的角色替换。我在文档中没有找到任何关于此的内容。哪些字符应该有相同的待遇?我怎么知道的?
最重要的是,我该如何获取文件名数组中的 é
字符?
编辑
removeObject 方法中使用的fileName
变量是通过从 PList 文件中获取字符串并将其提供给以下方法构造的:
+ (NSString*) fileNameWithString:(NSString*)str
{
NSString* fileName = str;
NSCharacterSet* charactersToRemove = [NSCharacterSet characterSetWithCharactersInString:@".:/\\"];
fileName = [[fileName componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@"#"];
fileName = [fileName stringByAppendingString:@".jpg"];
return fileName;
}
最佳答案
NSArray
的 NSLog
输出以 \Unnnn
转义形式显示所有非 ASCII 字符。但这只是 NSLog
打印它的方式,所以这应该不是问题。
我认为这是“预组合”与“分解”字符的问题。 HFS 文件系统在文件名中使用分解 字符,因此é
存储为两个 Unicode 字符:
U+0065 + U+0301 = "e" + COMBINING ACUTE ACCENT
(NSLog 将其打印为 e\U0301
)。
这与单个 Unicode 字符(预组合 形式)不同
U+00E9 = "é"
因此,字符串 yahoéo.jpg
将不会在数组中找到,如果它
字符以预组合形式存储。
如果这确实是问题所在,您可以通过以下方式解决
使用 NSString
的 precomposedStringWithCanonicalMapping
或 decomposedStringWithCanonicalMapping
方法将所有文件名规范化为预组合或分解形式。
备注:
- 字符串的预组合和分解版本将以相同的方式显示(例如
é
)。 NSString
的compare:
方法将字符串的两个版本视为相等(除非您使用NSLiteralSearch
选项调用它)。NSString
的isEqual:
方法认为字符串的两个版本是不同的,removeObject:
使用它来查找要删除的对象。
关于iphone - ios - 使强调的字符在文件路径中很好地显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17891547/