Использование 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();
Другие вопросы по тегам