Я хотел бы сохранить объект, содержащий данные 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.
Как вы «храните символы UTF 8 в объектах»? Вы храните byte или char? char всегда имеет кодировку UTF-16, так как же получить UTF-8?
Как именно вы «храните символы UTF-8 в объектах»? Какую проблему вы видите?
Приведите пример, иллюстрирующий проблему; то есть пример, который пытается и не может сохранить символы UTF-8. (Глядя на ваш код, я не вижу очевидной причины, по которой не стал бы работает ...)
Строковые элементы MyClass неправильно закодированы. Я загружу пример, как только вернусь к своему компьютеру.
ObjectOutputStream полностью поддерживает строки, они не «ломаются». Итак, либо ваша входная строка уже сломана (откуда вы ее взяли?), Либо ваша выходная строка не отображается должным образом (как вы это делаете?).




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, все работает как надо.
Объекты
Stringв ваших объектахMyClassнеправильно закодированы?