簡體   English   中英

在BufferedReader之后使用DataInputStream

[英]Using DataInputStream after 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() ,則輸出圖像與輸入圖像完全相同。 怎么回事

BufferedReader已緩沖,這意味着它將盡可能多地讀取(增大緩沖區的大小),以最大程度地減少對基礎Reader或Stream的調用次數。 因此,它不適合以后更改流。 通常,除非您真的知道自己在做什么,否則更改底層流或閱讀器的包裝是個壞主意。

在這種情況下,最簡單的解決方案是使用不建議使用的方法。 您可以編寫自己的readLine()替代品,但這可能只會帶來更多問題,而無濟於事。

@deprecated此方法不能正確將字節轉換為字符。

的確如此,但是對於ASCII字符,它可能會滿足您的需求。

我得到了答案,為什么在我在dataInputStream之前使用bufferedReader時,圖像會稍微向上和向左移動,以及為什么在底部有黑條? 闡釋:

如果圖片尺寸為400 * 400,則標頭后有160000個字節需要讀取。 由於bufferedReader會額外讀取並保留在其緩沖區中,因此假定它在標頭之后額外增加25000個字節。 因此,當dataInputStream開始讀取圖像強度時,它將從第25001個字節開始讀取。 並且將第2500001個字節放在第一個位置,因此所有像素強度都向后移250000個位置,即向上移62行,向左移200個像素。 由於最后一個字節少了25000個字節,因此從像素(160000-25000 + 1)到160000寫入了0,因此底部的黑色條帶被寫入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM