简体   繁体   中英

Using DataInputStream after BufferedReader

A sample binary PGM file is as follows:

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

like

在此处输入图片说明

When I try to read the file using the following code:

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();
        }
    }
}

It works perfectly and gives the following output:

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

but it shows that the DataInputStream.readLine() method is deprecated. So to avoid using this method I tried using the BufferedReader.readLine() method, as follows:

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();
        }
    }
}

And the output changed to:

P5
# This is a comment
10 10
255

and it seems that the second while loop ie

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

is not working.

What could be the possible reason for this?

I tried using a larger image ie 400x400 image instead of 10x10 image, 在此处输入图片说明

and tried to copy the bytes from one image and paste them into the new file using the following code:

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();
        }
    }
}

and the output image came out like this:

在此处输入图片说明

If I use DataInputStream.readLine() in the whole code then the output image comes exactly the same as the input image. How is it happening?

BufferedReader is buffered which means it will read as much as possible (up the the buffer's size) to minimise the number of calls to the underlying Reader or Stream. As such it is not suitable for changing the stream later. In general it is bad idea to change the wrapper of an underlying stream or reader unless you really know what you are doing.

In this case, the simplest solution is to use the deprecated method. You could write your own replacement for readLine() but that might just introduce more problems than it helps.

@deprecated This method does not properly convert bytes to characters.

This is true, however for ASCII characters it will probably do what you need.

I got the answer to why the image is shifted a bit upwards and leftwards and why there is black strip at the bottom when I use bufferedReader before dataInputStream . Explaination:

we had 160000 bytes to read after header if the image size was 400*400. Since bufferedReader reads extra and keep in its buffer, lets assume that it 25000 bytes extra after the header. So when the dataInputStream starts to read the image intensities, it gets to read from the 25001th byte. And it puts the 2500001th byte at 1st position, and therefore all the pixel intensities are shifted 250000 position behind ie 62 rows up and 200 pixels left. Since there are 25000 bytes less in the last so 0 is written from pixel (160000-25000+1) to 160000, hence the black strip at the bottom.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM