如何缩短NSString可能包括例如。 Emojis到HFS +文件名允许的最大长度 [英] How to shorten an NSString that might include e.g. Emojis to the maximal length allowed for a HFS+ filename
问题描述
苹果文档说:
[...]当前文件系统,如HFS +(Mac OS X使用)创建具有255个字符限制的文件名[...]符号可能实际上需要相当于九个英文字符来存储[...]尝试创建更长的名称时应考虑这一点。
[...] current file systems such as HFS+ (used by Mac OS X) allow you to create filenames with a 255-character limit [...] symbols may actually take up to the equivalent of nine English characters to store [...] This should be considered when attempting to create longer names.
如何以一个真正短于255个字符的方式限制NSString的长度,即使它包含可能需要多个字符的符号store?
How do I limit the length of a NSString in a way that it is truly shorter than 255 characters, even when it includes symbols that might take more than one character to store?
我在下面添加了我的当前实现。如果我添加例如emojis到字符串,而 length
回答结果字符串将远小于255,它仍然太长,不能被 NSSavePanel
作为文件名。
I add my current implementation below. If i add e.g. emojis to the string, while length
answers the resulting string would be by far smaller than 255, it is still too long to be accepted by a NSSavePanel
as file name.
NSRange stringRange = {0, MIN([fileName length], 255)};
stringRange = [fileName rangeOfComposedCharacterSequencesForRange:stringRange];
fileName = [fileName substringWithRange:stringRange];
推荐答案
rangeOfComposedCharacterSequencesForRange:
基本上是做与你想要的相反:你给它一个计数255组成字符的范围,它给你的字节范围,包括那些,可能会比你想要的更多。
rangeOfComposedCharacterSequencesForRange:
is basically doing the opposite of what you want: you give it a range that counts 255 composed characters, and it gives you the byte range that encompasses those, which might end up being much more than you want.
不幸的是,相反,你必须手动计数字节。这不是太难,但 enumerateSubstringsInRange:options:usingBlock:
。传递 NSStringEnumerationByComposedCharacterSequences
为选项提供了它所说的:每个组成的字符轮流。然后你可以用 lengthOfBytesUsingEncoding:
来计算每个的大小,传递你将使用的最终编码(大概是UTF-8)。
Unfortunately to do the reverse, you have to count the bytes manually. This isn't too hard, however, with enumerateSubstringsInRange:options:usingBlock:
. Passing NSStringEnumerationByComposedCharacterSequences
for the options gives you exactly what it says: each composed character in turn. You can then count the size of each with lengthOfBytesUsingEncoding:
, passing the final encoding you'll be using (presumably UTF-8). Add up the bytes, keeping track of the character-based index, and stop when you've seen too many.
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];
这篇关于如何缩短NSString可能包括例如。 Emojis到HFS +文件名允许的最大长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!