4

如果编码类型未知,如何将纯文本 (.txt) 文件转换为字符串?

我正在开发一项功能,允许用户将 txt 文件导入我的应用程序。这意味着该文件可以在任意数量的应用程序中创建,使用被认为对纯文本文件有效的各种编码中的任何一种。我的理解是这可能包括(ASCII、UTF-8、UTF-16、UTF-16BE、UTF-16LE、UTF-32、UTF-32BE、UTF-32LE 或 EBCDIC?!)

使用以下方法进展顺利:

NSString *txtFileAsString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&errorReading];

然后,用户提供了一个文件,该文件在导入时导致内容为空。我在 XCode 调试中查看了该文件,并看到 Cocoa 错误 261,NSStringEncoding=4。

我知道的:

  • 用户提供的文件是使用名为 knowtes 的应用程序创建的
  • 该文件在 Mac OS X 上使用 TextEdit、TextWranger 等打开
  • 该文件包含“特殊字符”,例如变音符号(咆哮:为什么变音符号上的“u”没有变音符号?!)
  • Finder 信息显示:

种类:文字

文本/纯文本;字符集=utf-16le

我猜测文件的 utf-16le 编码是关键,因为我期待一个 NSUTF8 文件。我尝试使用 ASCII 作为最低公分母。它没有崩溃,但在原始文件中不存在的一些字符中进行了捏造。

NSString *txtFileAsString = [NSString stringWithContentsOfFile:path encoding:NSASCIIStringEncoding error:&errorReading];

所以我尝试先将文件转换为 NSData,希望它可以消除识别编码的需要。那没起效。

    NSData *txtFileData = [NSData dataWithContentsOfFile:path];
    NSString *txtFileAsString = [[NSString alloc]initWithData:txtFileData encoding:NSUTF8StringEncoding];

这导致我提出几个问题:

  1. 是否没有一种通用方法可以将纯文本文件内容(无论编码如何)转换为字符串(即最低公分母)?我相信这曾经是目的initWithContentsOfFile,不幸的是现在已弃用。ASCIStringEncoding 不起作用。
  2. 有什么关于将 NSUTF16 编码文件转换为我需要以不同于 NSUTF8 的方式处理的字符串?
  3. 假设文件实际上是 URF16LE,为什么以下建议也不起作用?

    NSString *txtFileAsString = nil;
    if (path !=nil) {
      NSData *txtFileData = [NSData dataWithContentsOfFile:path];
      NSString *txtFileAsString = [[NSString alloc]initWithData:txtFileData encoding:NSASCIIStringEncoding];
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF8StringEncoding];
    }
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF16StringEncoding];
    }
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF16LittleEndianStringEncoding];
    }
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF16BigEndianStringEncoding];
    }
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF32StringEncoding];
    }
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF32LittleEndianStringEncoding];
    }
    if (!txtFileAsString) {
      txtFileAsString = [[NSString alloc] initWithData:txtFileData encoding:NSUTF32BigEndianStringEncoding];
    }}
    
4

1 回答 1

3

有时stringWithContentsOfFile:usedEncoding:error:可以完成这项工作(特别是如果文件有Byte Order Mark):

NSError *error;
NSStringEncoding encoding;
NSString *string = [NSString stringWithContentsOfFile:path usedEncoding:&encoding error:&error];

请注意,usedEncoding不应将这种形式与仅具有encoding参数的类似名称的方法相混淆。

于 2015-07-15T23:02:03.957 回答