Использование DataInputStream после BufferedReader

Пример двоичного файла PGM выглядит следующим образом:

P5
# This is a comment
10 10
255
#image intensity information in bytes that I am unable to copy paste here

лайк

Когда я пытаюсь прочитать файл, используя следующий код:

import java.io.*;

public class Pgm_reader2 {
    public static void main(String[] args) throws IOException {
        try {
            FileInputStream inRaw = new FileInputStream("A.pgm");
            DataInputStream dis = new DataInputStream(inRaw);
            int i = 0;
            while(i < 4){
                System.out.println(dis.readLine());
                i++;
            }
            while(dis.available() != 0){
                System.out.print(dis.readUnsignedByte() + " ");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

Он отлично работает и дает следующий вывод:

P5
# This is a comment
10 10
255
0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0 255 255 255 255 255 255 255 255 255 255 0

но это показывает, что DataInputStream.readLine() метод устарел. Поэтому, чтобы избежать использования этого метода, я попытался использовать BufferedReader.readLine() метод, следующим образом:

import java.io.*;

public class Pgm_reader2 {
    public static void main(String[] args) throws IOException {
        try {
            FileInputStream inRaw = new FileInputStream("A.pgm");
            DataInputStream dis = new DataInputStream(inRaw);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inRaw));
            int i = 0;
            while(i < 4){
                System.out.println(bufferedReader.readLine());
                i++;
            }
            while(dis.available() != 0){
                System.out.print(dis.readUnsignedByte() + " ");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

И вывод изменился на:

P5
# This is a comment
10 10
255

и кажется, что второй while петля т.е.

while(dis.available() != 0){
    System.out.print(dis.readUnsignedByte() + " ");
}

не работает.

Что может быть причиной этого?

Я попытался использовать увеличенное изображение, например, изображение 400x400 вместо изображения 10x10,

и попытался скопировать байты из одного изображения и вставить их в новый файл, используя следующий код:

import java.io.*;

public class Pgm_reader2 {
    public static void main(String[] args) throws IOException {
        try {
            FileInputStream inRaw = new FileInputStream("A.pgm");
            FileOutputStream outRaw = new FileOutputStream("B_test.pgm");
            DataInputStream dis = new DataInputStream(inRaw);
            DataOutputStream dos = new DataOutputStream(outRaw);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inRaw));
            String line = null;
            int i = 0;
            while(i < 4){
                line = bufferedReader.readLine();
                dos.writeBytes(line);
                dos.writeBytes("\n");
                i++;
            }
            int intbyte = 0;
            while(dis.available() != 0){
                intbyte = dis.readUnsignedByte();
                dos.writeByte(intbyte);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

и выходное изображение получилось так:

Если я использую DataInputStream.readLine() во всем коде выходное изображение будет точно таким же, как и входное изображение. Как это происходит?

2 ответа

Решение

BufferedReader буферизуется, что означает, что он будет читать как можно больше (до размера буфера), чтобы минимизировать количество вызовов к базовому Reader или Stream. Как таковой он не подходит для изменения потока позже. В общем, плохая идея менять оболочку основного потока или читателя, если вы действительно не знаете, что делаете.

В этом случае самое простое решение - использовать устаревший метод. Вы можете написать свою собственную замену для readLine(), но это может создать больше проблем, чем помогает.

@deprecated Этот метод неправильно конвертирует байты в символы.

Это правда, однако для символов ASCII он, вероятно, будет делать то, что вам нужно.

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

у нас было 160000 байт для чтения после заголовка, если размер изображения был 400*400. Так как bufferedReader читает дополнительные данные и хранит их в своем буфере, давайте предположим, что после заголовка оно дополнительно на 25000 байт. Итак, когда dataInputStream начинает читать интенсивность изображения, начинает читать с 25001-го байта. И он помещает 2500001-й байт в 1-ю позицию, и, следовательно, все интенсивности пикселей смещаются на 250000 позиций, то есть на 62 строки вверх и на 200 пикселей влево. Так как в последнем случае на 25000 байтов меньше, то 0 записывается от пикселя (160000-25000 + 1) до 160000, отсюда и черная полоса внизу.

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