-->

如何缩短一个NSString可能包括,例如,表情符号,以允许一个HFS +文件名的最大长度(How

2019-10-24 08:59发布

苹果的文件说:

[...]当前的文件系统,如HFS +(由Mac OS X使用)允许您创建一个255个字符限制的文件名[...]符号实际上可能需要长达九个英文字符存储[相当。 ..]这应该尝试创建较长的名称时,必须考虑。

如何限制的NSString的长度的方式,它是真正的短于255个字符,即使它包括可能需要不止一个字符来存储符号?

我下面添加我目前的执行情况。 如果我如表情符号的字符串,而length回答得到的字符串将远远大于255时,它仍然是太长,可以通过接受NSSavePanel作为文件名。

NSRange stringRange = {0, MIN([fileName length], 255)};
stringRange = [fileName rangeOfComposedCharacterSequencesForRange:stringRange];
fileName = [fileName substringWithRange:stringRange];

Answer 1:

rangeOfComposedCharacterSequencesForRange:基本上是这样做的,你想的正好相反:你给它才是最重要组成255个字符的范围内,它为您提供了包括这些,这最终可能会比你想要更多的字节范围。

不幸的是做相反的,你必须手动计数的字节数。 这是不是太辛苦,但是,与enumerateSubstringsInRange:options:usingBlock: 传递NSStringEnumerationByComposedCharacterSequences的选项给你正是它说:依次在每个组成字符。 然后,你可以指望每个的大小lengthOfBytesUsingEncoding:传递您将使用最后的编码(大概是UTF-8)。 添加了字节,跟踪基于字符的索引,当你见过太多停止。

NSString * s = /* String containing multibyte characters */;
NSUInteger maxBytes = ...;
__block NSUInteger seenBytes = 0;
__block NSUInteger truncLength = 0;
NSRange fullLength = (NSRange){0, [s length]};

[s enumerateSubstringsInRange:fullLength
                      options:NSStringEnumerationByComposedCharacterSequences
                   usingBlock:
    ^(NSString *substring, NSRange substringRange,
      NSRange _, BOOL *stop)
    {
        seenBytes += [substring lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
        if( seenBytes > maxBytes ){
            *stop = YES;
            return;
        }
        else {
            truncLength += substringRange.length;
        }
}];

NSString * truncS = [s substringToIndex:truncLength];


Answer 2:

正如@JoshCaswell建议,我没有修改这个答案对一个类似问题。 它显然不工作(我写了几个测试),但它似乎很奇怪我。 这样一个明显的任务不能这么复杂实现?

// filename contains the NSString that should be shortened
NSMutableString *truncatedString = [NSMutableString string];
NSUInteger bytesRead = 0;
NSUInteger charIdx = 0;

while (bytesRead < 250 && charIdx < [fileName length])
{
    NSRange range = [fileName rangeOfComposedCharacterSequencesForRange:NSMakeRange(charIdx, 1)];
    NSString *character = [fileName substringWithRange:NSMakeRange(charIdx, range.length)];
    bytesRead += [character lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    charIdx = charIdx + range.length;
    if (bytesRead <= 250)
        [truncatedString appendString:character];
}


文章来源: How to shorten an NSString that might include e.g. Emojis to the maximal length allowed for a HFS+ filename