Отображение содержимого текстового файла, загруженного с устройства flutter

#flutter #dart #utf-8 #readfile

#flutter #dart #utf-8 #readfile

Вопрос:

Используя функции _localFile и ReadFile, приведенные ниже, я могу выбрать правильный файл и прочитать его как байты, однако я не могу преобразовать обратно в правильный текст в файле. При использовании декодирования utf8 я получаю следующую ошибку

Необработанное исключение: FormatException: неожиданный байт расширения (со смещением 10).

Список int, который я получаю при чтении файла, начинается с

 [80, 75, 3, 4, 20, 0, 8, 8, 8, 0, 135, 117, 116, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 95, 114, 101, 108, 115, 47, 46, 114, 101, 108, 115, 173, 210, 193, 74, 3, 49, 16, 6, 224, 123, 159, 98, 153, 123, 119, 182, 85, 68, 100, 179, 189, 136, 208, 155, 72, 125, 128, 144, 204, 238, 6, 155, 76, 72, 166, 90, 223, 222, 80, 10, 186, 80, 86, 193, 30, 51, 249, 231, 231, 35, 164, 221, 28, 253, 190, 122, 167, 148, 29, 7, 5, 171, 186, 129, 138, 130, 97, 235, 194, 160, 224, 117, 247, 180, 188, 135, 77, 183, 104, 95, 104, 175, 165, 68, 242, 232, 98, 174, 202, 78, 200, 10, 70, 145, 248, 128, 152, 205, 72, 94, 231, 154, 35, 133, 114, 211, 115, 242, 90, 202, 49, 13, 24, 181, 121, 211, 3, 225, 186, 105, 238, 48, 253, 236, 128, 110, 210, 89, 109, 173, 130, 180, 181, 43, 168, 118, 159, 145, 254, 215, 141, 158, 68, 91, 45, 26, 13, 39, 90, 198, 84, 182, 147, 56, 202, 165, 92, 167, 129, 68, 129, 101, 243, 92, 198, 249, 148, 168, 75, 51, 224, 101, 208, 250, 239, 32, 238, 123, 103, 232, 145, 205, 193, 83, 144, 75, 46, 5...
 

и имеет длину 24596, где в текстовом файле всего 5601 символ. Как мне получить содержимое файла, который я прочитал?
Спасибо

 Future<List<int>> readFile() async {
    try {
      final file = await _localFile;
      // Read the file.
      List<int> contents = await file.readAsBytes();
      return contents;
    } catch (e) {
      print(e);
      // If encountering an error, return 0.
      return [0];
    }
  }

  Future<File> get _localFile async {
    final path = await FlutterDocumentPicker.openDocument();
    return File('$path');
  }
 

Комментарии:

1. Вероятно, файл не имеет кодировки utf8. Используя allowMalformed параметр utf8.decode (см. Документ ), ошибка устраняется и некоторые символы заменяются? В этом случае попробуйте расшифровать содержимое файла с помощью онлайн-инструмента, чтобы найти правильный декодер. Простой способ проверить кодировку файла в Windows — открыть его в Блокноте и посмотреть на предлагаемый тип в «Сохранить как» (обычно он распознает наиболее распространенные кодировки, но это не правило).

2. Спасибо, я обнаружил, что файл закодирован с использованием ANSI, как мне тогда расшифровать это в dart?

Ответ №1:

Чтобы List<int> правильно преобразовать данные, вам нужно знать, как они были закодированы. Если вы не знаете, может быть полезно попробовать открыть файл с помощью блокнота Windows и посмотреть, какая кодировка предлагается вам в окне «Сохранить как», и / или выполнить некоторые тесты преобразования с помощью онлайн-инструментов (это практичный подход, потому что не всегда возможно понять впросмотрите, какая кодировка использовалась). Затем вы можете продолжить декодирование:

  • для UTF-8 вы можете использовать встроенный dart:convert пакет;
  • для UTF-16 и UTF-32 вы можете использовать utf пакет (он снят с производства, но я не нашел альтернатив);
  • для ANSI: символы ANSI после 128 меняются в зависимости от страны, поэтому должна быть указана точная кодировка («кодовая страница»), используемая. Например, в Западной Европе (для латиницы) это может быть Windows-1250 или Windows-1252. Единственный пакет, который я нашел, который поддерживает эти кодировки, — это charset_converter (он поддерживает различные кодировки, но доступен только для Android и iOS, поскольку он использует собственный API этих систем, например, в Android на API, предлагаемом Java).

Пример для ANSI (который, кажется, относится к вашему случаю), для кодовой страницы «windows1250»:

(после включения charset_converter в зависимости и его импорта)

 List<int> contents = await file.readAsBytes();
var decoded = await CharsetConverter.decode("windows1250", Uint8List.fromList(contents));
 

Комментарии:

1. Я использовал пакет charset_converter с кодовой страницей windows1252 и могу вернуться к тому, что отображается в блокноте, однако, когда декодируется ноль, декодирование файла останавливается, и я могу вернуться только к тому, что отображается в блокноте, а не в текстовом редакторе. Ниже приведено то, что отображается в блокноте, PK00tpQ00000000000000 00_rels/.relsADD2C1J1E0{9Fb99{w B6UDd B3 BD 88ЛH} 80 90 CC EE 9BLH A6Z DF DEP BAPV C13 F9 E7 E7 # A4 DD FD BEz A7 94 AB BA 81 8A 82a EB E0u.

2. Файл notepad кодируется с использованием Microsoft OOXML

3. Файл, который я пытаюсь прочитать, является файлом docx

4. Нормально, что вы видите его как в блокноте (если вы используете текстовый виджет). Отображение docx сильно отличается от отображения чисто текстового файла. Самым простым решением было бы найти подходящий пакет; попробуйте выполнить поиск в pub.dev и в предыдущих потоках Stackoverflow, посвященных docx в flutter. Я видел, что есть пакет flutter_filereader, который может вам подойти, но я никогда его не пробовал. Но имейте в виду, что с некоторыми пакетами (например, url_launcher) вы можете открывать файлы docx в Android / ios, но открывать их в новом окне, а не внутри вашего приложения, поэтому, возможно, они не для вас.

5. Я смог открыть их в других приложениях, используя file_reader и open_file, однако мне нужен текст в локальном приложении

Ответ №2:

Для чтения файлов в кодировке ANSI enough_convert пакет может их считывать, и это работает на всех платформах! 😀