BufferedReader、DataInputStream



BufferedReader的用法(分享)
public class BufferdReader extends Reader
從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。

通常,Reader 所作的每個讀取請求都會導致對基礎字符或字節流進行相應的讀取請求。因此,建議用 BufferedReader 包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)。例如,

BufferedReader in= new BufferedReader(new FileReader("foo.in"));
將緩衝指定文件的輸入。如果沒有緩衝,則每次調用 read() 或 readLine() 都會導致從文件中讀取字節,並將其轉換爲字符後返回,而這是極其低效的。

可以對使用 DataInputStream 進行按原文輸入的程序進行本地化,方法是用合適的 BufferedReader 替換每個 DataInputStream。

import java.io.InputStreamReader;
import java.io.BufferedReader;
public class BufferedReaderDemo
{
      public static void main(String[] args) throws java.io.IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("請輸入一段文字,可包含空白:");
        String text = br.readLine();
        System.out.println("您輸入的文字:"+text);
}


DataInputStream是InputStream的子類,專門負責讀取使用DataOutputStream輸出的數據,此類的定義如下:

public class DataInputStream extends FilterInputStream implements DataInput

此類繼承自FilterInputStream類(FilterInputStream是InputStream的子類),同時實現DataInput接口,在DataInput接口中定義了一系列讀入各種數據的方法。

U提示:DataInput接口的作用。

DataInput接口是讀取數據的操作接口,與DataOutput接口提供的各種writerXxx()方法對應,在此接口中定義了一系列的readXxx()方法,這些方法在DataInputStream類中都有實現。一般在操作時不會直接使用到此接口,而主要使用DataInputStream類完成讀取功能,只有在對象序列化時纔有可能直接利用此接口讀取數據,這一點在講解Externalizable接口時再爲讀者介紹


DataInputStream和DataOutputStream都是Java中輸入輸出流的裝飾類,用起來很方便。今天就來討論一下使用該類時候遇到的編碼問題。
  1. package com.vincent.example;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8.   
  9. public class TestDataStream {  
  10.     public static void main(String[] args) {  
  11.         // 使用DataInputStream,DataOutputStream寫入文件且從文件中讀取數據。  
  12.         try {  
  13.             // Data Stream寫到輸入流中  
  14.             DataOutputStream dos = new DataOutputStream(new FileOutputStream(  
  15.                     "datasteam.txt"));  
  16.             dos.writeBytes("世界"); //按2字節寫入,都是寫入的低位  
  17.             dos.writeChars("世界"); // 按照Unicode寫入  
  18.             // 按照UTF-8寫入(UTF8變長,開頭2字節是由writeUTF函數寫入的長度信息,方便readUTF函數讀取)  
  19.             dos.writeUTF("世界");   
  20.             dos.flush();  
  21.             dos.close();  
  22.   
  23.             // Data Stream 讀取  
  24.             DataInputStream dis = new DataInputStream(new FileInputStream(  
  25.                     "datasteam.txt"));  
  26.             // 讀取字節  
  27.             byte[] b = new byte[2];  
  28.             dis.read(b);  
  29.             System.out.println(new String(b, 02));  
  30.   
  31.             // 讀取字符  
  32.             char[] c = new char[2];  
  33.             for (int i = 0; i < 2; i++) {  
  34.                 c[i] = dis.readChar();  
  35.             }  
  36.             System.out.println(new String(c, 02));  
  37.   
  38.             // 讀取UTF  
  39.             System.out.println(dis.readUTF());  
  40.   
  41.             dis.close();  
  42.         } catch (IOException e) {  
  43.             e.printStackTrace();  
  44.         }  
  45.     }  
  46. }  
package com.vincent.example;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestDataStream {
        public static void main(String[] args) {
                // 使用DataInputStream,DataOutputStream寫入文件且從文件中讀取數據。
                try {
                        // Data Stream寫到輸入流中
                        DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                                        "datasteam.txt"));
                        dos.writeBytes("世界"); //按2字節寫入,都是寫入的低位
                        dos.writeChars("世界"); // 按照Unicode寫入
                        // 按照UTF-8寫入(UTF8變長,開頭2字節是由writeUTF函數寫入的長度信息,方便readUTF函數讀取)
                        dos.writeUTF("世界"); 
                        dos.flush();
                        dos.close();

                        // Data Stream 讀取
                        DataInputStream dis = new DataInputStream(new FileInputStream(
                                        "datasteam.txt"));
                        // 讀取字節
                        byte[] b = new byte[2];
                        dis.read(b);
                        System.out.println(new String(b, 0, 2));

                        // 讀取字符
                        char[] c = new char[2];
                        for (int i = 0; i < 2; i++) {
                                c[i] = dis.readChar();
                        }
                        System.out.println(new String(c, 0, 2));

                        // 讀取UTF
                        System.out.println(dis.readUTF());

                        dis.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

使用16進制方式打開文件如下:

可以看出,第一個“世界”已經被截斷,兩個漢字都只被寫入了低位,因此肯定亂碼。

  1. package com.vincent.example;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8.   
  9. public class TestDataStream {  
  10.     public static void main(String[] args) {  
  11.         // 使用DataInputStream,DataOutputStream寫入文件且從文件中讀取數據。  
  12.         try {  
  13.             // Data Stream寫到輸入流中  
  14.             DataOutputStream dos = new DataOutputStream(new FileOutputStream(  
  15.                     "datasteam.txt"));  
  16.             dos.write("世界".getBytes()); // 按UTF8編碼(我的系統默認編碼方式)寫入  
  17.             //dos.write("世界".getBytes("GBK"));  //指定其他編碼方式  
  18.             dos.writeChars("世界"); // 按照Unicode寫入  
  19.             // 按照UTF-8寫入(UTF8編碼長度可變,開頭2字節是由writeUTF函數寫入的長度信息,方便readUTF函數讀取)  
  20.             dos.writeUTF("世界");   
  21.             dos.flush();  
  22.             dos.close();  
  23.   
  24.             // Data Stream 讀取  
  25.             DataInputStream dis = new DataInputStream(new FileInputStream(  
  26.                     "datasteam.txt"));  
  27.             // 讀取字節  
  28.             byte[] b = new byte[6];  
  29.             dis.read(b);  
  30.             System.out.println(new String(b, 06));  
  31.   
  32.             // 讀取字符  
  33.             char[] c = new char[2];  
  34.             for (int i = 0; i < 2; i++) {  
  35.                 c[i] = dis.readChar();  
  36.             }  
  37.             System.out.println(new String(c, 02));  
  38.   
  39.             // 讀取UTF  
  40.             System.out.println(dis.readUTF());  
  41.   
  42.             dis.close();  
  43.         } catch (IOException e) {  
  44.             e.printStackTrace();  
  45.         }  
  46.     }  
  47. }  
package com.vincent.example;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestDataStream {
        public static void main(String[] args) {
                // 使用DataInputStream,DataOutputStream寫入文件且從文件中讀取數據。
                try {
                        // Data Stream寫到輸入流中
                        DataOutputStream dos = new DataOutputStream(new FileOutputStream(
                                        "datasteam.txt"));
                        dos.write("世界".getBytes()); // 按UTF8編碼(我的系統默認編碼方式)寫入
                        //dos.write("世界".getBytes("GBK"));  //指定其他編碼方式
                        dos.writeChars("世界"); // 按照Unicode寫入
                        // 按照UTF-8寫入(UTF8編碼長度可變,開頭2字節是由writeUTF函數寫入的長度信息,方便readUTF函數讀取)
                        dos.writeUTF("世界"); 
                        dos.flush();
                        dos.close();

                        // Data Stream 讀取
                        DataInputStream dis = new DataInputStream(new FileInputStream(
                                        "datasteam.txt"));
                        // 讀取字節
                        byte[] b = new byte[6];
                        dis.read(b);
                        System.out.println(new String(b, 0, 6));

                        // 讀取字符
                        char[] c = new char[2];
                        for (int i = 0; i < 2; i++) {
                                c[i] = dis.readChar();
                        }
                        System.out.println(new String(c, 0, 2));

                        // 讀取UTF
                        System.out.println(dis.readUTF());

                        dis.close();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }
}

文件打開如下:


可以看出,讀取前6字節並按照UTF-8解碼就可以避免亂碼。值得注意的是,String構造函數也可以指定對byte數組作其他編碼方式的解碼。例如:new String(b,0,6,"GBK")。同時使用writeUTF和readUTF可以免去程序猿對於長度的考慮,因爲這兩個函數爲我們解決了長度問題,寫入了文件,因此我們無需關心。但這樣就使用了額外的空間去記錄長度信息。

DataInput 接口用於從二進制流中讀取字節,並根據所有 Java 基本類型數據進行重構。
對於此接口中的所有數據讀取例程來說,如果在讀取所需字節數之前已經到達文件末尾 (end of file),則將拋出 EOFException(IOException 的一種)。如果因爲到達文件末尾以外的其他原因無法讀取字節,則將拋出 IOException 而不是 EOFException。尤其是,在輸入流已關閉的情況下,將拋出 IOException。
----------------------------------------------------
在什麼時候用datainputstream 在什麼時候用bufferedreader?
DataInputStream 可以從基礎輸入流中讀取基本 Java 數據類型比如 dataInputStream.readDouble();
dataInputStream.readInteger();dataInputStream.readLong();
bufferedreader從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。
ByteArrayOutputStream 緩存流 和磁盤無關,不需要關閉
BufferedReader從字符輸入流中讀取文本,緩衝各個字符,從而實現字符、數組和行的高效讀取。注意是從字符輸入流中讀取,所以常用BufferedReader br=new BufferedReader(new InputStreamReader(in));
BufferedReader(Reader in)
          創建一個使用默認大小輸入緩衝區的緩衝字符輸入流。
context.getFilesDir().getPath()獲取路徑 getFilesDir()獲取該應用程序數據文件夾的絕對路徑



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章