2009-08-29 3 views
15

NSString을 파일에서 읽을 때 initWithContentsOfFile:usedEncoding:error:을 사용할 수 있으며 파일 인코딩을 추측 할 수 있습니다.NSData에서 NSString을 만들 때 인코딩 추측

내 유일한 옵션은 initWithData:encoding:이지만 명시 적으로 인코딩을 전달해야하지만 NSData에서 생성합니다. 파일 대신 NSData으로 작업 할 때 인코딩을 올바르게 추측 할 수 있습니까?

답변

12

일반적으로 할 수 없습니다. 그러나 UTF-8 파일을 확실히 신뢰할 수 있습니다. 파일이 유효한 UTF-8 인 경우 다른 인코딩이 될 가능성이 거의 없습니다 (모든 바이트가 ASCII 범위에있는 경우는 예외). " 확장 ASCII "인코딩 (UTF-8 포함)을 사용하면 동일한 결과를 얻을 수 있습니다. 모든 유니 코드 인코딩에는 식별 할 수있는 선택적인 BOM도 있습니다. 합리적인 접근 방식은 다음과 같습니다.

  • 유효한 BOM을 찾으십시오. 있는 경우 적절한 인코딩을 사용하십시오.
  • 그렇지 않으면 UTF-8로 해석하십시오. initWithData:data encoding:NSUTF8StringEncoding을 호출하고 결과가 0이 아닌지 확인하여이 작업을 수행 할 수 있습니다.
  • 이것이 실패하면 -[NSString defaultCStringEncoding] (로캘에 맞는 추측을 제공)과 같은 기본 8 비트 인코딩을 사용하십시오. 그것은

다양한 다른 인코딩을 시도하고 "정크"의 모든 문자가 중간에 쓰레기와 문자의 적은 순서를 가지고있는 하나를 선택하여 마지막 단계에서 추측을 개선하려고 가능하다 문자, 공백 또는 일반적인 구두점이 아닙니다. 이것은 실제로 신뢰성이 없지만 복잡성을 크게 증가시킵니다. 간단히 말해, 사용 가능한 모든 인코딩을 처리하려면 TextEdit의 기능을 수행해야합니다. 즉, 사용자에게 의사 결정을 취소하십시오.

아, 한 가지 더 : 10.5부터 인코딩은 문서화되지 않은 com.apple.TextEncoding 확장 속성에 파일로 저장되는 경우가 많습니다. +[NSString stringWithContentsOfFile:] 또는 이와 유사한 파일을 열면 자동으로 사용됩니다.

23
이 아이폰 OS 8 및 OS X 10.10에서

NSString에 새로운 API :

오브젝티브 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)에 언급 된 순간 방법을 명시하지 않지만 :

  1. 이 목록의 3 번째 옵션을 지정하지 않고 제안 문자열 인코딩의 배열 (, 모든 문자열 인코딩은 고려되지만 배열에있는 인코딩은 더 높은 선호도를 갖습니다. 또한 배열의 인코딩 순서가 중요합니다. 첫 번째 인코딩은 배열의 두 번째 인코딩보다 높은 우선 순위를가집니다.
  2. 배열 사용하지 않는 문자열 인코딩 (이 목록의 문자열 인코딩은 c onsidered 전혀)
  3. 만 제안 된 문자열 인코딩은 손실이 허용되는지 여부를 나타내는
  4. 부울 옵션을 고려하는지 여부를 나타내는 부울 옵션은
  5. 신비에 대한 substitude하기 위해 특정 문자열을 제공하는 옵션은
  6. 현재의 바이트 사용자의 언어
  7. 사전의 값 (예를 들어 잘못된 유형이있는 경우 데이터가 윈도우

에 의해 NSS의 값을 생성 여부를 나타내는 부울 옵션 tringEncodingDetectionSuggestedEncodingsKey가 배열이 아님) 예외가 throw됩니다.

사전의 값을 알 수없는 경우 (예 : 제안 된 문자열 인코딩의 값이 유효한 인코딩이 아님) 값은 무시됩니다.

예 (스위프트) : 그것의 이유가처럼 그냥 디코딩 된 문자열을 원하는 인코딩에 대해 상관하지 않는 경우

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

let encoding =

+0

을 제거 할 수 있습니다 보인다 아직 공식 아니야. 나는 그것을 반환하는 -2147482362 PDF NSData 인코딩으로 실행했습니다. – FireDragonMule

+0

그것이 작동하도록 의도되었는지는 확실하지 않습니다. pdf는 문자열이 아니며이 메서드는 NSData에서 문자열에 대한 인코딩을 찾습니다. 당신의 의도는 무엇입니까? – HAS

+0

NSData로 SDK를 통해 PDF를 가져오고 있습니다. 난 그냥 인코딩이 무엇인지 또는 거기에 인코딩 경우 모르는 원인이 webview 바로 지금 표시 문제가 있습니다. – FireDragonMule