Использование 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, отсюда и черная полоса внизу.