當從文件中讀取NSString
時,我可以使用initWithContentsOfFile:usedEncoding:error:
,它會猜測文件的編碼。從NSData創建NSString時猜測編碼
當我從NSData
創建它時,儘管我唯一的選擇是initWithData:encoding:
,我必須明確地通過編碼。當我使用NSData
而不是文件時,如何可靠地猜出編碼?
當從文件中讀取NSString
時,我可以使用initWithContentsOfFile:usedEncoding:error:
,它會猜測文件的編碼。從NSData創建NSString時猜測編碼
當我從NSData
創建它時,儘管我唯一的選擇是initWithData:encoding:
,我必須明確地通過編碼。當我使用NSData
而不是文件時,如何可靠地猜出編碼?
一般來說,你不能。但是,您可以非常可靠地識別UTF-8文件 - 如果文件的有效性爲UTF-8,則不太可能它應該是任何其他編碼(除非所有字節都在ASCII範圍內,在這種情況下,任何「擴展ASCII「編碼,包括UTF-8,會給你相同的結果)。所有的Unicode編碼也有一個可選的BOM標識它們。因此,合理的做法是:
initWithData:data encoding:NSUTF8StringEncoding
並檢查結果是否爲非零來做到這一點。-[NSString defaultCStringEncoding]
(它提供了適合於區域設置的猜測)。這是可能試圖通過嘗試各種不同的編碼,並選擇具有序列最少的信件,垃圾在中間,其中「垃圾」是的任何字符的一個,以提高在最後一步猜不是字母,空格或常見的標點符號。這會顯着增加複雜性,但實際上並不可靠。
簡而言之,爲了能夠處理所有可用的編碼,您需要做TextEdit的工作:將決策分流給用戶。
哦,還有一件事:從10.5開始,編碼通常與文件一起存儲在未記錄的com.apple.TextEncoding擴展屬性中。如果您使用+[NSString stringWithContentsOfFile:]
或類似文件打開文件,則會自動使用該文件(如果存在)。
在iOS系統中8和OS X 10.10有上NSString
一個新的API:
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 Session 204 (page 270)正式提到:
- 建議串編碼的陣列(沒有指定此列表中的第三選項,所有字符串編碼都會被考慮,但陣列中的編碼將具有更高的優先級;此外,陣列中編碼的順序很重要:第一個編碼比第二個編碼具有更高的優先級)
- 數組字符串編碼不能使用(這個列表中的字符串編碼不會是c onsidered在所有)
- 僅指示所建議的字符串編碼是否被視爲
- 指示有損是否允許一個布爾選項布爾選項
- ,給出了一個特定的字符串可分別代替用於神祕的選項字節
- 當前用戶的語言
- 布爾選項指示是否是由Windows
產生的數據。如果在字典中的值有錯誤的類型(例如,NSS的價值tringEncodingDetectionSuggestedEncodingsKey不是數組),拋出異常。
如果字典中的值未知(例如,建議的字符串編碼數組中的值不是有效的編碼),則值將被忽略。
例(SWIFT):
var convertedString: NSString?
let encoding = NSString.stringEncoding(for: data, encodingOptions: nil, convertedString: &convertedString, usedLossyConversion: nil)
如果你只是想解碼串並不在乎編碼,您可以刪除let encoding =
好像有就是爲什麼它是有原因的尚未官方。我用它的PDF NSData編碼運行它返回-2147482362。 – FireDragonMule
我不太確定這是否如此。 pdf不是一個字符串,並且此方法從「NSData」中查找字符串的編碼。你的意圖是什麼? – HAS
我正在通過SDK以NSData格式檢索pdf。我只是在webview中顯示問題,因爲我不知道編碼是什麼,甚至是編碼。 – FireDragonMule