Использование PrintWriter с потоками байтов
Я проверяю PrintWriter
класс, который может обрабатывать потоки символов и байтов. Все прошло гладко, когда я попробовал с потоками символов, теперь я тестировал его с потоками байтов, и всякий раз, когда я печатаю то, что он читает, он всегда показывает ноль (исключение). Вот код:
package com.files.ex1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
public class ex1 {
public static void main(String[] args) {
PrintWriter oPW;
try {
oPW = new PrintWriter(new ObjectOutputStream(new FileOutputStream("data.txt")));
oPW.write("1\n");
oPW.write("2\n");
oPW.write("3\n");
oPW.flush();
oPW.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
Это класс, который пытается прочитать и всегда печатает ноль:
package com.files.ex1;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ex1_2 {
public static void main(String[] args) {
ObjectInputStream oOIS;
try {
oOIS = new ObjectInputStream(new FileInputStream("data.txt"));
String s = (String) oOIS.readObject();
System.out.println(s);
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
}
}
Кроме того, каковы преимущества использования этого класса? Для потоков символов я могу просто использовать BuffedReadear
или же BufferedWriter
оптимизировать чтение или запись соответственно, и это также имеет flush()
метод. И в чем преимущество использования PrintWriter
с потоками байтов? С помощью ObjectOutputStream
один работает, когда я пытаюсь сделать операции выше.
1 ответ
Причина, по которой вы получаете нулевое значение, заключается в том, что вы используете readObject
на ObjectInputString
, но вы не сериализовали никаких объектов Java. ObjectInputString.readObject
должен использоваться с ObjectOutputString.writeObject
,
PrintWriter
документы прямо заявляют, что
Он не содержит методов для записи необработанных байтов, для которых программа должна использовать потоки незакодированных байтов.
Вы должны использовать только PrintWriter
для текста. Он предоставляет полезные методы, с которыми вы можете быть знакомы, потому что System.out
имеет интерфейс печати.
Вы должны только реально использовать ObjectOutput/InputStream
при написании и чтении сериализованных объектов Java. Формат сериализации - двоичные данные (в отличие, например, от JSON/XML). Эти объекты должны реализовывать интерфейс Serializable.
Вы можете улучшить производительность записи и чтения потоков некодированных байтов, используя BufferedOutputStream и BufferedInputStream соответственно.
Как правило, классы с суффиксом "Reader" и суффиксом "Writer" предназначены для потоков с кодированным текстом. Они содержат полезные методы для разбора строк и строк из текстовых потоков. Они никогда не должны использоваться для передачи двоичных данных.
В вашем примере вы записываете только текстовые данные в файл и считываете эти текстовые данные обратно, поэтому используйте:
oPW = new PrintWriter(new FileOutputStream("data.txt"));
oPW.println("1");
для написания и
oOIS = new BufferedReader(new FileInputStream("data.txt"));
String s = oOIS.readLine(); // "1"
для чтения.
Если бы вы читали и записывали двоичные данные, вы бы сделали это вместо этого:
os = new FileOutputStream("data.bin");
os.write(new byte[]{ 1, 2, 3 });
и читать:
is = new FileInputStream("data.bin");
byte[] buf = new byte[3];
is.read(buf); // buf now equals {1, 2, 3}
Если бы вы читали и писали объекты Java, вы бы сделали это вместо этого:
oos = new ObjectOutputStream(new FileOutputStream("data.bin"));
Foo foo = new Foo(...);
oos.writeObject(foo);
и читать:
ois = new ObjectInputStream(new FileInputStream("data.bin"));
Foo foo = (Foo) ois.readObject();