Преобразовать 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 и вижу ошибку Какао 261, NSStringEncoding=4.

Что я знаю:

  • Предоставленный пользователем файл был создан с помощью приложения под названием Knowtes
  • Файл открывается с помощью TextEdit, TextWranger и т. Д. В Mac OS X
  • Файл содержит "специальные символы", такие как умляуты (rant: почему у "u" на умлауте нет умлаута?!)
  • Finder Info отображает:

Вид: текст

текст / равнина; кодировка = 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];
    }}
    

1 ответ

Решение

Иногда stringWithContentsOfFile:usedEncoding:error: может выполнить работу (особенно если файл имеет метку порядка байтов):

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

Обратите внимание, это исполнение с usedEncoding не следует путать с одноименным методом, который просто имеет encoding параметр.

Другие вопросы по тегам