Объекты хранилища Java с символами UTF 8

Я хотел бы сохранить объект, содержащий данные UTF-8, в файл. К сожалению, ничего из того, что я пробовал, пока не работает. Буду очень признателен за ваши предложения. Мой код выглядит так:

public static void saveData(MyClass myData) {
    try (FileOutputStream fs = new FileOutputStream("data.ser");
            ObjectOutputStream os = new ObjectOutputStream(fs)) {

        ArrayList<MyClass> dataOld = new ArrayList<>();
        ArrayList<MyClass  dataNew = getData();
        for (int i = 0; i < dataOld.size(); i++) {
            dataNew.add(dataOld.get(i));
        }
        dataNew.add(myData);
        os.writeObject(dataNew);

    } catch (FileNotFoundException e) {
        System.out.println("File not found");
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static ArrayList<MyClass> getData() {
    ArrayList<MyClass> data= null;
    try (FileInputStream fi = new FileInputStream("data.ser"); ObjectInputStream os = new ObjectInputStream(fi)) {

        data= (ArrayList<MyClass>) os.readObject();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    return data;
}

Это решение работает для любой ситуации, если я не храню в объектах символы UTF 8.

Объекты String в ваших объектах MyClass неправильно закодированы?

Ashishkumar Singh 14.08.2018 15:25

Как вы «храните символы UTF 8 в объектах»? Вы храните byte или char? char всегда имеет кодировку UTF-16, так как же получить UTF-8?

piet.t 14.08.2018 15:27

Как именно вы «храните символы UTF-8 в объектах»? Какую проблему вы видите?

Peter Štibraný 14.08.2018 15:30
Не работает ничего не значит. Скажите точно, что ожидается и что произойдет.
Serge Ballesta 14.08.2018 15:55

Приведите пример, иллюстрирующий проблему; то есть пример, который пытается и не может сохранить символы UTF-8. (Глядя на ваш код, я не вижу очевидной причины, по которой не стал бы работает ...)

Stephen C 14.08.2018 15:55

Строковые элементы MyClass неправильно закодированы. Я загружу пример, как только вернусь к своему компьютеру.

Matthias Maier 14.08.2018 16:01
ObjectOutputStream полностью поддерживает строки, они не «ломаются». Итак, либо ваша входная строка уже сломана (откуда вы ее взяли?), Либо ваша выходная строка не отображается должным образом (как вы это делаете?).
Thilo 14.08.2018 16:27
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
7
161
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

The string elements of MyClass are not properly encoded.

Что ж, я бы не ожидал, что они будут такими. Строки сериализуются как измененный UTF-8; см. https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html. Если вы попытаетесь просмотреть данные с помощью стандартной программы просмотра UTF-8, подсчет байтов и другие данные, скорее всего, "испортят" текст ... до некоторой степени.

(Но если строковые данные не имеют смысла как модифицированный UTF-8, проблема в том, что текст в исходных строках уже был искажен ...)

Я думаю, что настоящая проблема здесь в ваших ожиданиях.

Поток данных, создаваемый ObjectOutputStream, является двоичным, а не текстовым. Он не кодируется в UTF-8 ... потому что невозможно напрямую закодировать произвольный поток как UTF-8. И если вы попытаетесь отобразить / декодировать вывод ObjectOutputStream, как если бы это был UTF-8, вы бы получили ошибки декодирования или мусор.

Решение зависит от того, чего вы пытаетесь достичь:

  • Если вы пытаетесь отправить закодированный экземпляр вашего MyClass по текстовому каналу, то вам нужно закодировать двоичный поток, используя что-то вроде Base64. Результат не будет разборчивым (читаемым человеком), но вы сможете отменить процесс и создать экземпляры MyClass, эквивалентные оригиналам.

  • Если вы пытаетесь сделать вывод ObjectOutputStream удобочитаемым ... это не сработает. Формат сериализации объектов Java в основном двоичный. Если вы хотите, чтобы сериализованные данные были (человеческими) читаемыми, вам следует использовать другой формат сериализации; например JSON или XML.

Спасибо за исчерпывающий ответ; Я понял ошибку сейчас. Строки, которые я хранил в объектах MyClass, были закодированы в ANSI, поскольку они происходят из файла, который использует ANSI, и когда я создавал объекты, я не учел этого. Он отлично работал с обычными символами, однако при использовании специальных символов вывод был просто мусором - даже несмотря на то, что программа чтения файлов явно использовала UTF-8. Теперь, когда исходные строки тоже UTF-8, все работает как надо.

Matthias Maier 14.08.2018 19:09

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