猜创建从NSData的一个NSString时编码(Guess encoding when creat

2019-07-04 01:43发布

当读取NSString从一个文件,我可以使用initWithContentsOfFile:usedEncoding:error:它会猜测文件的编码。

当我从一个创建NSData虽然我唯一的选择是initWithData:encoding:在这里我要明确地传递编码。 我怎样才能可靠地估计编码时我一起工作NSData而不是文件?

Answer 1:

在一般情况下,你不能。 然而,你可以很可靠地识别UTF-8的文件 - 如果文件是有效的UTF-8,这是不太可能,这应该是任何其他的编码(除非所有字节都在ASCII范围,在这种情况下,任何“扩展ASCII”编码,包括UTF-8,会给你同样的结果)。 所有的Unicode编码还有一个可选的BOM识别它们。 因此,合理的做法是:

  • 寻找一个有效的BOM。 如果有一个,使用适当的编码。
  • 否则,请尝试将其解释为UTF-8。 您可以通过调用做到这一点initWithData:data encoding:NSUTF8StringEncoding ,如果结果是非零和检查。
  • 如果失败,则使用默认的8位编码,如-[NSString defaultCStringEncoding]它提供了一个区域设置适当的猜测)。

可能试图通过尝试各种不同的编码,并选择具有序列最少的信件,垃圾在中间,其中“垃圾”是不是一个字母,空格或常用标点符号的任何字符的一个,以提高在最后一步猜标记。 这将显著增加复杂性,而没有实际是可靠的。

总之,要能够处理你需要做文字编辑所做的所有可用编码:分流到用户的决定。

哦,还有一两件事:为10.5,编码通常存储与在未记录的com.apple.TextEncoding扩展属性的文件。 如果你打开一个文件+[NSString stringWithContentsOfFile:]或类似的,这将自动(如果存在)使用。



Answer 2:

在iOS中8和OS X 10.10有一个新的API NSString

Objective-C的

+ (NSStringEncoding)stringEncodingForData:(NSData *)data
                          encodingOptions:(NSDictionary *)opts
                          convertedString:(NSString **)string
                      usedLossyConversion:(BOOL *)usedLossyConversion;

迅速

open class func stringEncoding(for data: Data,
                   encodingOptions opts: [StringEncodingDetectionOptionsKey : Any]? = nil, 
                 convertedString string: AutoreleasingUnsafeMutablePointer<NSString?>?, 
                    usedLossyConversion: UnsafeMutablePointer<ObjCBool>?) -> UInt

现在你可以让框架做了猜测,在我的经验,作品真的很好!

从报头(文件没有说明在目前的方法,但它在被正式提到WWDC会议204(第270页) :

  1. 建议串编码的阵列(没有指定此列表中的第三选项,所有串编码被考虑,但在阵列中的那些将具有较高的优先级;此外,在阵列中的编码的顺序是重要的:第一编码具有比第二个阵列中的更高的偏好)
  2. 字符串编码的数组不使用(在此列表中的字符串编码将根本不会被考虑)
  3. 布尔选项仅指示建议的字符串编码是否被认为是
  4. 布尔选项指示有损是否允许
  5. ,给出了一个特定的字符串可分别代替了神秘字节的选择
  6. 当前用户的语言
  7. 布尔选项指示数据是否是由Windows产生

如果在字典中的值具有错误的类型(例如,NSStringEncodingDetectionSuggestedEncodingsKey的值不是数组),则抛出异常。

如果在字典中的值是未知的(例如,建议的串编码的阵列中的值不是有效的编码),这些值将被忽略。

实施例(SWIFT):

var convertedString: NSString?
let encoding = NSString.stringEncoding(for: data, encodingOptions: nil, convertedString: &convertedString, usedLossyConversion: nil)

如果你只是想解码串并不在乎编码,您可以删除let encoding =



文章来源: Guess encoding when creating an NSString from NSData