對於任何程序設計語言而言,輸入輸出(I/O)系統都是比較復雜的而且還是比較核心的。在java.io.包中提供了相關的API.
java中流的概念划分
流的方向:
-
- 輸入流:數據源到程序(inputStream,Reader讀進來)
- 輸出流:程序到目的地(OutPutStream,Writer寫出去)
處理數據單元:
-
- 字節流:按照字節讀取數據(InputStream,OutputStream)
- 字符流:按照字符讀取數據(Reader,Writer)
功能不同
-
- 節點流:直接從數據源或目的地讀寫數據
- 處理流:不直接連接到數據源或目的地,是處理流的流,童工對其他流的處理提高程序的性能。
Jdk提供的流繼承了四大類:InputStream(字節輸入流),OutputStream(字節輸出流),Reader(字符輸入流),Writer(字符輸出流)。
以下是java中io中常用的流。
InputStream
抽象類java.io.InputStream是所有字節輸入流類型的父類,該類中定義了以字節為單位讀取數據的基本方法,並在其子類中進行了分化和實現.
三個基本的read方法:
- int read()
- int read(byte[] buffer)
- int read(byte[] buffer,int offset,int length)
其他方法:
- void close()
- int available()
- skip(long n)
- boolean markSupported()
InputStream類層次
import java.io.File ; import java.io.InputStream ; import java.io.FileInputStream ; public class InputStreamDemo{ public static void main(String args[]) throws Exception{ // 異常拋出,不處理 // 第1步、使用File類找到一個文件 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 // 第2步、通過子類實例化父類對象 InputStream input = null ; // 准備好一個輸入的對象 input = new FileInputStream(f) ; // 通過對象多態性,進行實例化 // 第3步、進行讀操作 byte b[] = new byte[1024] ; // 數組大小由文件決定 int len = 0 ; int temp = 0 ; // 接收每一個讀取進來的數據 while((temp=input.read())!=-1){ // 表示還有內容,文件沒有讀完 b[len] = (byte)temp ; len++ ; } // 第4步、關閉輸出流 input.close() ; // 關閉輸出流\ System.out.println("內容為:" + new String(b,0,len)) ; // 把byte數組變為字符串輸出 } };
OutputStream
java.io.OutputStream與java.io.InputStream對應,是所有字節輸出流類型的抽象父類。
三個基本的write方法:
- void write(int c)
- void write(byte[] buffer)
- void write(byte[] buffer,int offset,int length)
其他方法:
- void close()
- void flush()
OutputStream類層次
import java.io.File ; import java.io.OutputStream ; import java.io.FileOutputStream ; public class OutputStreamDemo{ public static void main(String args[]) throws Exception{ // 異常拋出,不處理 // 第1步、使用File類找到一個文件 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 // 第2步、通過子類實例化父類對象 OutputStream out = null ; // 准備好一個輸出的對象 out = new FileOutputStream(f) ; // 實例化 // 第3步、進行寫操作 String str = "Hello World!!!" ; // 准備一個字符串 byte b[] = str.getBytes() ; // 只能輸出byte數組,所以將字符串變為byte數組 out.write(b) ; // 寫入數據 // 第4步、關閉輸出流 // out.close() ; // 關閉輸出流 } };
Reader
抽象類java.io.Reader是所有字符輸入流類型的父類,其中聲明了用於讀取字符流的有關方法.
三個基本的read方法:
- int read()
- int read(char[] cbuf)
- int read(char[] cbuf,int offset,int length)
其他方法:
- void close()
- boolean ready()
- skip(long n)
- boolean markSupported()
- void mark(int readAheadLimit)
- void reset()
Reader類層次
import java.io.File ; import java.io.Reader ; import java.io.FileReader ; public class ReaderDemo{ public static void main(String args[]) throws Exception{ // 異常拋出,不處理 // 第1步、使用File類找到一個文件 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 // 第2步、通過子類實例化父類對象 Reader input = null ; // 准備好一個輸入的對象 input = new FileReader(f) ; // 通過對象多態性,進行實例化 // 第3步、進行讀操作 char c[] = new char[1024] ; // 所有的內容都讀到此數組之中 int temp = 0 ; // 接收每一個內容 int len = 0 ; // 讀取內容 while((temp=input.read())!=-1){ // 如果不是-1就表示還有內容,可以繼續讀取 c[len] = (char)temp ; len++ ; } // 第4步、關閉輸出流 input.close() ; // 關閉輸出流 System.out.println("內容為:" + new String(c,0,len)) ; // 把字符數組變為字符串輸出 } };
Writer
java.io.Writer與java.io.Reader類對應,是所有字符輸出流類型的共同父類.
五個基本的write方法:
- void write(int c)
- void write(char[] cbuf)
- void write(char[] cbuf,int offset,int leng)
- void write(String string)
- void write(String string,int offset,int length)
其它方法:
- void close()
- void flush()
Writer類層次
import java.io.File ; import java.io.Writer ; import java.io.FileWriter ; public class WriterDemo{ public static void main(String args[]) throws Exception{ // 異常拋出,不處理 // 第1步、使用File類找到一個文件 File f= new File("d:" + File.separator + "test.txt") ; // 聲明File對象 // 第2步、通過子類實例化父類對象 Writer out = null ; // 准備好一個輸出的對象 out = new FileWriter(f) ; // 通過對象多態性,進行實例化 // 第3步、進行寫操作 String str = "Hello World!!!" ; // 准備一個字符串 out.write(str) ; // 將內容輸出,保存文件 // 第4步、關閉輸出流 out.flush() ; // 強制性清空緩沖區中的內容 // out.close() ; // 此時,沒有關閉 } };
拷貝實例:
import java.io.* ; public class Copy{ public static void main(String args[]){ if(args.length!=2){ // 判斷是否是兩個參數 System.out.println("輸入的參數不正確。") ; System.out.println("例:java Copy 源文件路徑 目標文件路徑") ; System.exit(1) ; // 系統退出 } File f1 = new File(args[0]) ; // 源文件的File對象 File f2 = new File(args[1]) ; // 目標文件的File對象 if(!f1.exists()){ System.out.println("源文件不存在!") ; System.exit(1) ; } InputStream input = null ; // 准備好輸入流對象,讀取源文件 OutputStream out = null ; // 准備好輸出流對象,寫入目標文件 try{ input = new FileInputStream(f1) ; }catch(FileNotFoundException e){ e.printStackTrace() ; } try{ out = new FileOutputStream(f2) ; }catch(FileNotFoundException e){ e.printStackTrace() ; } if(input!=null && out!=null){ // 判斷輸入或輸出是否准備好 int temp = 0 ; try{ while((temp=input.read())!=-1){ // 開始拷貝 out.write(temp) ; // 邊讀邊寫 } System.out.println("拷貝完成!") ; }catch(IOException e){ e.printStackTrace() ; System.out.println("拷貝失敗!") ; } try{ input.close() ; // 關閉 out.close() ; // 關閉 }catch(IOException e){ e.printStackTrace() ; } } } }
*** 在一般操作輸入輸出內容就需要使用字節或字符流,但是有些時候需要將字符流變成字節流的形式,或着將字節流變成字符流的形式,所以就需要另外一組轉換流操作類
-
- OutputStreamWriter:是Writer的子類,將輸出的字符流變成字節流。
- InputStreamReader:是Reader的子類,將輸入的字節流變成字符流。
轉換步驟:
如果以文件操作為例,則在內存總的字符數據需要通過OutputStreamWriter變成字節流保存在文件中,讀取的時候需要將讀入的字節流通過InputStreamReader變成字符流
例如,將字節的文件輸出流以字符的形式輸出
import java.io.* ; public class OutputStreamWriterDemo{ public static void main(String args[]) throws Exception { // 所有異常拋出 File f = new File("d:" + File.separator + "test.txt") ; Writer out = null ; // 字符輸出流 out = new OutputStreamWriter(new FileOutputStream(f)) ; // 字節流變為字符流 out.write("hello world!!") ; // 使用字符流輸出 out.close() ; } };
讀的時候亦可以使用字符流的形式讀取字節流的文件
import java.io.* ; public class InputStreamReaderDemo01{ public static void main(String args[]) throws Exception{ File f = new File("d:" + File.separator + "test.txt") ; Reader reader = null ; reader = new InputStreamReader(new FileInputStream(f)) ; // 將字節流變為字符流 char c[] = new char[1024] ; int len = reader.read(c) ; // 讀取 reader.close() ; // 關閉 System.out.println(new String(c,0,len)) ; } };