Мне нужно закодировать мои файлы в «ISO-8859-1». Я знаю, как это сделать с помощью такого ридера:
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(src), "ISO-8859-1"))
Но я спрашиваю, как вот так кодировать DataInputStream.
Мое отклонение прямо сейчас:
DataInputStream dit = new DataInputStream(new BufferedInputStream(
new FileInputStream(src)))
Я бы предпочел решение, в котором параметр кодирования находится в отклонении. Данные, которые я хочу прочитать, были записаны с помощью DataOutputStream.
Метод импорта и метод экспорта для DataStreams:
public void importDST(String src) throws FileNotFoundException, IOException{
try (DataInputStream dit = new DataInputStream(new BufferedInputStream(new FileInputStream(src)))) {
while(dit.available() > 0) {
pupils.add(new Pupil(dit.readInt(), dit.readInt(), dit.readUTF(), dit.readUTF(), dit.readChar(),
dit.readUTF(), dit.readInt(), dit.readInt(), dit.readInt(), dit.readUTF(), dit.readUTF(), dit.readUTF(), dit.readUTF(),
dit.readUTF(), dit.readUTF()));
}
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
throw e;
}
}
public void exportDST(String dest, ArrayList<Pupil> pupils) throws FileNotFoundException, IOException{
this.pupils = pupils;
try (DataOutputStream dot = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)))) {
for (Pupil p : this.pupils) {
dot.writeInt(p.getId());
dot.writeInt(p.getNumber());
dot.writeUTF(p.getFirstname());
dot.writeUTF(p.getLastname());
dot.writeChar(p.getGender());
dot.writeUTF(p.getReligion());
dot.writeInt(p.getDay());
dot.writeInt(p.getMonth());
dot.writeInt(p.getYear());
dot.writeUTF(p.getStreet());
dot.writeUTF(p.getPlz());
dot.writeUTF(p.getLocation());
dot.writeUTF(p.getShortName());
dot.writeUTF(p.getClassName());
dot.writeUTF(p.getKvLastname());
}
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
throw e;
}
}
класс Ученик:
public class Pupil implements Serializable{
private int id;
private int number;
private String firstname;
private String lastname;
private char gender;
private String religion;
private int day;
private int month;
private int year;
private String street;
private String plz;
private String location;
private String shortName;
private String className;
private String kvLastname;
public Pupil() {}
public Pupil(int id, int number, String firstname, String lastname, char gender,
String religion, int day, int month, int year, String street, String plz, String location,
String shortName, String className, String kvLastname) {
this.id = id;
this.number = number;
this.firstname = firstname;
this.lastname = lastname;
this.gender = gender;
this.religion = religion;
this.day = day;
this.month = month;
this.year = year;
this.street = street;
this.plz = plz;
this.location = location;
this.shortName = shortName;
this.className = className;
this.kvLastname = kvLastname;
}
}




Что касается ObjectInputStream, в документации указано, что
An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.
Также обратите внимание:
Only objects that support the java.io.Serializable or java.io.Externalizable interface can be read from streams.
То есть считанные данные ранее были сериализованы (или экстернализованы) с использованием ObjectOutputStream и заданы объекты, реализующие Serializable (или Externalizable). Таким образом, вы будете иметь дело с кодировкой для любых атрибутов String в методах readObject и `writeObject 'ваших Serializable объектов.
Что касается DataInputStream, см. Этот ответ: DataInputStream и UTF-8
Вам нужно будет указать кодировку при создании String из прочитанных байтов.
Спасибо за вашу поставку. Это не совсем подходит моему коду, потому что я использую такие методы, как readInt () и readUTF (). Так что я не читаю байты
@Stefan, я думаю, это поможет подробнее рассказать о вашем деле. Вы написали предметы, которые нужно прочитать? Если нет, то как выглядят файлы? Если вы сами создаете файлы и хотите, чтобы они были в удобочитаемом формате, почему бы не сериализовать их в XML или JSON вместо использования DataInputStream? Если вы хотите читать / писать в двоичном формате, вам придется самостоятельно разграничивать данные, включая длину строк и т. д. Кодировка набора символов (например, ISO-8859-1) не имеет смысла для хранения целых чисел.
Данные из файла создаются DataOutputStream
Тогда что это за данные и как их записать в этот поток?
Ваш вопрос действительно не имеет смысла.
Потоки моделируют потоки байты. У них нет кодировки символов, это просто байты.
Читатели читают потоки символы. В конечном итоге это тоже потоки байтов, но есть кодировка символов, которая говорит, как преобразовать эти байты в символы. Таким образом, имеет смысл указать эту кодировку в конструкторе.
DataInputStream - это Stream: они читают двоичный файл, поэтому у них нет кодировки символов.
Почему тогда я не могу правильно прочитать все символы. У меня есть символы типа ö, ä, ü в моем файле, и они не отображаются после чтения из DataInputStream
@Stefan, пожалуйста, покажите минимальный воспроизводимый пример, показывающий, как данные записываются, а затем читаются (а не просто как вы создаете поток).
@Stefan в ваших примерах не показан пример, который записывает символы с диакритическими знаками, а затем неправильно их считывает. Пожалуйста, предоставьте минимальный воспроизводимый пример, а не только часть соответствующего кода.
Я обошел эту проблему, написав и прочитав только интенты и байты вместо строк. Я прочитал байтовые массивы и создал новую строку с кодировкой из нее. Вот измененный код:
Чтение:
public void importDST(String src) throws IOException{
try (DataInputStream dit = new DataInputStream(new BufferedInputStream(new FileInputStream(src)))) {
while (dit.available() > 0) {
Pupil p = new Pupil();
byte[] arr;
int len;
p.setId(dit.readInt());
p.setNumber(dit.readInt());
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setFirstname(new String(arr, "ISO-8859-1"));
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setLastname(new String(arr, "ISO-8859-1"));
p.setGender(dit.readChar());
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setReligion(new String(arr, "ISO-8859-1"));
p.setDay(dit.readInt());
p.setMonth(dit.readInt());
p.setYear(dit.readInt());
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setStreet(new String(arr, "ISO-8859-1"));
p.setPlz(dit.readInt());
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setLocation(new String(arr, "ISO-8859-1"));
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setShortName(new String(arr, "ISO-8859-1"));
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setClassName(new String(arr, "ISO-8859-1"));
len = dit.readInt();
arr = new byte[len];
dit.readFully(arr);
p.setKvLastname(new String(arr, "ISO-8859-1"));
pupils.add(p);
}
}
}
Пишу:
public void exportDST(String dest, ArrayList<Pupil> pupils) throws IOException{
this.pupils = pupils;
try (DataOutputStream dot = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)))) {
for (Pupil p : pupils) {
dot.writeInt(p.getId());
dot.writeInt(p.getNumber());
dot.writeInt(p.getFirstname().length());
dot.writeBytes(p.getFirstname());
dot.writeInt(p.getLastname().length());
dot.writeBytes(p.getLastname());
dot.writeChar(p.getGender());
dot.writeInt(p.getReligion().length());
dot.writeBytes(p.getReligion());
dot.writeInt(p.getDay());
dot.writeInt(p.getMonth());
dot.writeInt(p.getYear());
dot.writeInt(p.getStreet().length());
dot.writeBytes(p.getStreet());
dot.writeInt(p.getPlz());
dot.writeInt(p.getLocation().length());
dot.writeBytes(p.getLocation());
dot.writeInt(p.getShortName().length());
dot.writeBytes(p.getShortName());
dot.writeInt(p.getClassName().length());
dot.writeBytes(p.getClassName());
dot.writeInt(p.getKvLastname().length());
dot.writeBytes(p.getKvLastname());
}
}
}
Спасибо за все ваши ответы!
Кроме того, в ваших ловушках нет смысла: вы всегда повторно генерируете исключение. Иногда вам нужно перехватить исключение, если вы хотите, чтобы оно «перешагнуло» более широкий охват (например, если вы хотите распространить FileNotFoundException, но перехватить и обработать IOException). Здесь вы этого не сделаете, так что просто бросьте все свои уловы.