#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
пакет может их считывать, и это работает на всех платформах! 😀