【java基礎】--(3)javaIO詳細闡釋

來源:互聯網
上載者:User

1、總的4類

字元:Reader 和Writer

位元組:InputStream和OutputStream

2、Reader

六個子類BufferedReader,CharArrayReader,FilterReader,InputStreamReader,PipedReader,StringReader

2.1 BufferedReader

為什麼用它?

將緩衝指定檔案的輸入。如果沒有緩衝,則每次調用 read() 或 readLine() 都會導致從檔案中讀取位元組,並將其轉換為字元後返回,而這是極其低效的

工作原理?

從字元輸入資料流中讀取文本,緩衝各個字元,從而實現字元、數組和行的高效讀取。

什麼時候用?

建議用 BufferedReader 封裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)

InputStreamReader又封裝System.in

將控制台輸入,賦給字串

 

BufferedReader buf = new BufferedReader(                new InputStreamReader(System.in));        String str = null;        System.out.println("請輸入內容");        try{            str = buf.readLine();        }catch(IOException e){            e.printStackTrace();        }        System.out.println("你輸入的內容是:" + str);



跟蹤行號的緩衝字元輸入資料流

2.2 CharArrayReader

把字元數組作為源的輸入資料流的實現

緩衝字元數組,讀取每個字元的時候

 String strTmp = "abcdefghijklmnopqrstuvwxyz";   int intLen = strTmp.length();  char c[] = new char[intLen];  strTmp.getChars(0,intLen,c,0);
  CharArrayReader input1 = new CharArrayReader(c);  CharArrayReader input2 = new CharArrayReader(c,0,5); 
 int i;  System.out.println("input1 is : ");  while((i=input1.))!=-1){   System.out.print((char)i);  }  System.out.println();  System.out.println("input2 is : ");  while((i=input2.read())!=-1){   System.out.print((char)i);  }


 

2.3 FilterReader抽象類別

允許將字元推回到流的字元流

unread(char c) 回壓一個字元; unread(char c[]) 回壓數組 c 中全部字元 
unread(char c[],offset,int n) 回壓 c 中從 offset 開始的 n 個字元

編譯原理的一個重要的組成部分叫做詞法分析器,就是我上面提到的scanner。對於詞法剖析器來說,輸入就是原始碼,輸出就是一個一個的Token(想不出來合適的詞),通常詞法分析器會一個字元一個字元讀取,然後將將這些字元根據一定的規則群組成token的序列。有些時候,scanner需要超前讀下一個字元才能判斷當前的token是否已經結束。例如,int abc=5;這樣一個語句,詞法分析器要讀到=這個字元的時候才能確定abc是一個id,而不是"abc=",這樣=已經從輸入資料流中讀出來了,但是=又不屬於當前的Token,所以要把這個=退回去,這時就要用到pushback。

 

2.4InputStreamReader

是位元組流通向字元流的橋樑

要啟用從位元組到字元的有效轉換,可以提前從底層流讀取更多的位元組,使其超過滿足當前讀取操作所需的位元組。

為了達到最高效率,可要考慮在 BufferedReader 內封裝 InputStreamReader。例如:

 BufferedReader in   = new BufferedReader(new InputStreamReader(System.in));

 

用來讀取字元檔案的便捷類

樣本1:讀取字元檔案並寫到數組

路徑分隔字元:File.separator

 String fileName="D:"+File.separator+"hello.txt";        File f=new File(fileName);        char[] ch=new char[100];        Reader read=new FileReader(f);        int count=read.read(ch);        read.close();        System.out.println("讀入的長度為:"+count);        System.out.println("內容為"+new String(ch,0,count));


 

2.5 PipedReader

傳送的字元輸入資料流。

管道輸入輸出資料流類主要用於線程之間的通訊,不建議對這兩個對象嘗試使用單個線程,因為這樣可能死結線程。

樣本1:管道輸入輸出資料流類用於線程之間的通訊(讀管道中資料到字元數組,寫到管道中)

兩個線程

一個讀一個寫,都用到管道流,並返回管道流對象

主函數中得到輸入輸出對象

輸出對象與輸入對象打通管道 t1.connect(t2);

開啟各自線程 s.start(); r.start();

PipedInputStream,PipedOutputStream管道輸入輸出資料流類主要用於線程之間的通訊,不建議對這兩個對象嘗試使用單個線程,因為這樣可能死結線程。PipedReader,Pipedwriter字元輸入輸出資料流類和上面的類似import java.io.*;public class PipedStreamTest {  public static void main(String[] args) {  // TODO Auto-generated method stub        Sender s=new Sender();        Reciever r=new Reciever();        PipedWriter t1=s.getWriter();        PipedReader t2=r.getReader();        try{        t1.connect(t2);        }        catch(Exception e)        {         e.printStackTrace();        }        s.start();        r.start(); }}class Reciever extends Thread{      PipedReader in=new PipedReader();      public PipedReader getReader()      {       return in;      }      public void run()      {       char [] buf=new char[1024];      try{       int len=in.read(buf);       System.out.println("the following messageid:"+'\n'+         new String(buf,0,len));       in.close();      }      catch(Exception e)      {       e.printStackTrace();      }      }}class Sender extends Thread{    private PipedWriter out=new PipedWriter();    public PipedWriter getWriter()          {            return out;        }    public void run()    {     String strInfo=new String("hello,how are you doing?");     try{     out.write(strInfo);     out.close();     }     catch(Exception e)     {      e.printStackTrace();     }    }}


 

2.6StringReader

其源為一個字串的字元流。文本資訊當作記憶體中的字元一樣來處理

StringReader並不常用,因為通常情況下使用String更簡單一些。但是在一些需要Reader作為參數的情況下,就需要將String讀入到StringReader中來使用了

樣本1:統計單詞數

StreamTokenizer(reader);需要reader參數

檔案未結束:streamTokenizer.nextToken() != StreamTokenizer.TT_EOF

讀到單詞:streamTokenizer.ttype == StreamTokenizer.TT_WORD

public void countWordsInAString() {StreamTokenizer streamTokenizer = null;String stringToBeParsed = "The quick brown fox jumped over the lazy dog";StringReader reader = new StringReader(stringToBeParsed);int wordCount = 0;try {streamTokenizer = new StreamTokenizer(reader);while (streamTokenizer.nextToken() != StreamTokenizer.TT_EOF) {if (streamTokenizer.ttype == StreamTokenizer.TT_WORD)wordCount++;}System.out.println("Number of words in file: " + wordCount);} catch (FileNotFoundException ex) {ex.printStackTrace();} catch (IOException ex) {ex.printStackTrace();}}
3、Writer類

7個子類:BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

PrintWriter可以格式化輸出;與PrintStream的區別就是可以自動重新整理緩衝

FilterWriter沒有子類了

其他的跟reader匹配著用,都差不多

3.1BufferedWriter

將文本寫入字元輸出資料流,緩衝各個字元,從而提供單個字元、數組和字串的高效寫入

File file = new File(filepath);  02         //file.deleteOnExit();  03         file.createNewFile();  04            05         BufferedWriter write = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));  06         write.write("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");  07         write.write("<locals>\n");  08            09            10             write.write("\t</province>\n");  11             System.out.println("===完成省份:"+pro.getValue());  12         }  13         write.write("</locals>");  14         System.out.println("全部完成。。。。。。。。");  15         write.flush();  16         write.close(); 

3.2CharArrayWriter

操作的都是字元數組

此類實現一個可用作 Writer 的字元緩衝區。緩衝區會隨向流中寫入資料而自動成長。可使用 toCharArray() 和 toString() 擷取資料。

  

//顯示字元內容               array = charArrayWriter.toCharArray();   


//將字元數組內容存迴文件               CharArrayReader charArrayReader = new CharArrayReader(array);                              BufferedWriter bufWriter = new BufferedWriter(                    new FileWriter(file));                              char[] tmp = new char[1];               while(charArrayReader.read(tmp)!=-1)               {                   bufWriter.write(tmp);               }                 charArrayReader.close();               bufWriter.flush();               bufWriter.close();   

3.3FilterWriter

沒啥用

3.4OutputStreamWriter

是字元流通向位元組流的橋樑

為了獲得最高效率,可考慮將 OutputStreamWriter 封裝到 BufferedWriter 中,以避免頻繁調用轉換器。例如:

 

 Writer out   = new BufferedWriter(new OutputStreamWriter(System.out));

File f = new File("d:" + File.separator + "test.txt");          Writer out = null;          out = new OutputStreamWriter(new FileOutputStream(f));// 位元組流變為字元流          out.write("hello world");   // 使用字元流輸出          out.close(); 
3.5PipedWriter

見2.5PipedReader

3.6PrintWriter

向文本輸出資料流列印對象的格式化表示形式

是一種過濾流,也叫處理流。也就是能對位元組流和字元流進行處理

可以對下面幾種輸出資料流格式化字串輸出


PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));

首先,建立一個與指定檔案串連的FileWriter。實際上,我們通常會用BufferedWriter將起封裝起來用以緩衝輸出(......這裡面的我省略了)。然後為了格式化把它轉換成PrintWriter。

3.7StringWriter

一個字元流,可以用其回收在字串緩衝區中的輸出來構造字串。文本資訊當作記憶體中的字元一樣來處理

關閉 StringWriter 無效。此類中的方法在關閉該流後仍可被調用,而不會產生任何 IOException

StringWriter還有一個特點,那就是它能通過GetStringBuilder()方法來擷取一個System.Text.StringBuilder對象:

StringWriter strWriter = new StringWriter();...StringBuilder sb = strWriter.GetStringBuilder();sb.Insert(0, "Hey!! ");Console.WriteLine("-> {0}", sb.ToString());sb.Remove(0, "Hey!! ".Length);


StringWriter strWriter = new StringWriter();strWriter.WriteLine("Don't forget Mother's Day this year...");strWriter.Close();


 

 

 

4、InputStream

9個子類:AudioInputStream,ByteArrayInputStream,FileInputStream,FilterInputStream,InputStream,ObjectInputStream,PipedInputStream,SequenceInputStream,StringBufferInputStream

4.1AudioInputStream

音頻輸入資料流是具有指定音頻格式和長度的輸入資料流。長度用樣本幀表示,不用位元組表示。

4.2ByteArrayInputStream

ByteArrayInputStream 包含一個內部緩衝區,該緩衝區包含從流中讀取的位元組。內部計數器跟蹤 read 方法要提供的下一個位元組。

關閉 ByteArrayInputStream 無效。此類中的方法在關閉此流後仍可被調用

網路傳輸中我們往往要傳輸很多變數,我們可以利用ByteArrayOutputStream把所有的變數收集到一起,然後一次性把資料發送出去

int a=0; 6  int b=1; 7  int c=2; 8  ByteArrayOutputStream bout = new ByteArrayOutputStream(); 9  bout.write(a);10  bout.write(b);11  bout.write(c);12  byte[] buff = bout.toByteArray();13  for(int i=0; i<buff.length; i++)14   System.out.println(buff[i]);15  System.out.println("***********************");16  ByteArrayInputStream bin = new ByteArrayInputStream(buff);17  while((b=bin.read())!=-1) {18   System.out.println(b);


11 byte[] buff = bout.toByteArray();

13 DataInputStream dis = new DataInputStream(bin);

4.3PipedInputStream類


管道事實上是一個隊列 

樣本1:管道的輸入與輸出

import java.io.*; public class PipedIO //程式運行後將sendFile檔案的內容拷貝到receiverFile檔案中 {  public static void main(String args[]) {  try { //構造讀寫的管道流對象 PipedInputStream pis=new PipedInputStream(); PipedOutputStream pos=new PipedOutputStream(); //實現關聯 pos.connect(pis); //構造兩個線程,並且啟動。  new Sender(pos,"c:\\text2.txt").start();  new Receiver(pis,"c:\\text3.txt").start();  } catch(IOException e) { System.out.println("Pipe Error"+ e); }  } } //線程發送 class Sender extends Thread {  PipedOutputStream pos; File file; //構造方法 Sender(PipedOutputStream pos, String fileName) { this.pos=pos; file=new File(fileName); }  //線程運行方法 public void run() {  try { //讀檔案內容 FileInputStream fs=new FileInputStream(file); int data; while((data=fs.read())!=-1) { //寫入管道始端 pos.write(data); } pos.close();  } catch(IOException e) { System.out.println("Sender Error" +e); } } } //線程讀 class Receiver extends Thread {  PipedInputStream pis; File file; //構造方法 Receiver(PipedInputStream pis, String fileName) {  this.pis=pis; file=new File(fileName); }  //線程運行 public void run() {  try { //寫檔案流對象 FileOutputStream fs=new FileOutputStream(file); int data; //從管道末端讀 while((data=pis.read())!=-1) { //寫入本地檔案 fs.write(data); } pis.close();  } catch(IOException e) { System.out.println("Receiver Error" +e); } } } 


 

4.4FileInputStream

用於讀取諸像資料之類的原始位元組流。要讀取字元流,請考慮使用 FileReader

//建立兩個檔案,face.gif是已經存在檔案,newFace.gif是新建立的檔案 File inFile = new File("face.gif"); File outFile = new File("newFace.gif"); //建立流檔案讀入與寫出類 FileInputStream inStream = new FileInputStream(inFile); FileOutputStream outStream = new FileOutputStream(outFile); //通過available方法取得流的最大字元數 byte[] inOutb = new byte[inStream.available()]; inStream.read(inOutb);  //讀入流,儲存在byte數組 outStream.write(inOutb);  //寫出流,儲存在檔案newFace.gif中 inStream.close(); outStream.close(); 

4.5FilterInputStream

不知道有什麼必要?

4.6InputStream4.7ObjectInputStream

對象序列化和還原序列化

   Student stu1 = new Student(19, "zhangsan", 25, "huaxue");    Student stu1 = new Student(20, "lisi", 23, "wuli");    FileOutputStream fos = new FileOutputStream("student.txt");    ObjectOutputStream oos = new ObjectOutputStream(fos);    oos.writeObject(stu1);    oos.writeObject(stu2);    oos.close();    FileInputStream fin = new FileInputStream("student.txt");    ObjectInputStream ois = new ObjectInputStream(fin);    stu1 = (Student)ois.readObject();    stu2 = (Student)ois.readObject();    ois.close();

4.8SequenceInputStream(順序輸入資料流)

該類滿足讀取完第一個InputStream後轉去讀取第二個流的讀取要求。

該類滿足讀取完第一個InputStream後轉去讀取第二個流的讀取要求。使用Enumeration的情況下,它將繼續讀取所有InputStream流直到最後一個被讀完。text.txt與file2.txt一定要在目前的目錄下。*///Demonstrate squenced input.import java.io.*;import java.util.*;class InputStreamEnumerator implements Enumeration{ private Enumeration files; public InputStreamEnumerator(Vector files){  this.files = files.elements(); } public boolean hasMoreElements(){  return files.hasMoreElements(); } public Object nextElement(){  try{   return new FileInputStream(files.nextElement().toString());  }catch(Exception e){   return null;  } }}class SequenceInputStreamDemo{ public static void main(String[] args) throws Exception{  int c;  Vector files = new Vector();  files.addElement("text.txt");  files.addElement("file2.txt");  InputStreamEnumerator e = new InputStreamEnumerator(files);  InputStream input = new SequenceInputStream(e);  while((c=input.read())!=-1){   System.out.print((char)c);   }  input.close(); }}

4.9StringBufferInputStream

I/O類庫提供StringBufferInputStream類的本意是把字串轉換為位元組流,然後進行讀操作,但是在這個類的實現中僅僅使用了字元編碼的低8位,不能把字串中的所有字元(比如中文字元)正確轉換為位元組,因此這個類已經被廢棄,取而代之的是StringReader類

5、OutputStream

6個子類ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

5.1ByteArrayOutputStream

其中的資料被寫入一個 byte 數組。緩衝區會隨著資料的不斷寫入而自動成長。可使用 toByteArray()toString() 擷取資料。

樣本見4.2

5.2FileOutputStream

檔案輸出資料流是用於將資料寫入 FileFileDescriptor 的輸出資料流。

FileOutputStream 用於寫入諸像資料之類的原始位元組的流。

樣本見4.4

5.3ObjectOutputStream

將 Java 對象的基礎資料型別 (Elementary Data Type)和圖形寫入 OutputStream。

樣本見4.7

5.4FilterOutputStream

暫不研究

5.5OutputStream

暫不研究

5.6 PipedOutputStream

可以將管道輸出資料流串連到管道輸入資料流來建立通訊管道。

樣本見4.3

比較完整的類圖參見

http://blog.csdn.net/fenglian521/article/details/1324010

比較詳細的應用參見

http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.