從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。
通常,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接口的作用。
- 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();
- }
- }
- }
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進制方式打開文件如下:
可以看出,第一個“世界”已經被截斷,兩個漢字都只被寫入了低位,因此肯定亂碼。
- 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();
- }
- }
- }
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可以免去程序猿對於長度的考慮,因爲這兩個函數爲我們解決了長度問題,寫入了文件,因此我們無需關心。但這樣就使用了額外的空間去記錄長度信息。
DataInputStream 可以從基礎輸入流中讀取基本 Java 數據類型比如 dataInputStream.readDouble(); dataInputStream.readInteger();dataInputStream.readLong(); bufferedreader從字符輸入流中讀取文本,緩衝各個字符,從而提供字符、數組和行的高效讀取。
創建一個使用默認大小輸入緩衝區的緩衝字符輸入流。