閱讀526 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Java IO--字節流與字符流OutputStream/InputStream/Writer/Reader

1、流的概念


程序中的輸入輸出都是以流的形式保存的,流中保存的實際上全都是字節文件。

2、字節流與字符流


內容操作就四個類:OutputStream、InputStream、Writer、Reader

3、字節流


3.1字節輸出流OutputStream


Clonseable表示可以關閉的操作,因為程序運行到最後肯定要關閉。
Fluashable表示刷新,清空內存中的數據

import java.io.File ;
import java.io.OutputStream ;
import java.io.FileOutputStream ;
public class OutputStreamDemo01{
	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() ;						// 關閉輸出流
	}
};
在操作的時候,如果文件本身不存在,則會為用戶自動創建新文件。
在操作輸出流的時候,也可以使用write(int i)的方法寫出數據。
import java.io.File ;
import java.io.OutputStream ;
import java.io.FileOutputStream ;
public class OutputStreamDemo02{
	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數組
		for(int i=0;i<b.length;i++){		// 采用循環方式寫入
			out.write(b[i]) ;	// 每次隻寫入一個內容
		}
		// 第4步、關閉輸出流
		out.close() ;						// 關閉輸出流
	}
};

以上的操作中在寫入數據之後,文件之前的內容應經不存在了,因為在io操作中默認的情況是將其進行覆蓋的,那麼如果現在要想執行追加的功能,則必須設置追加的操作。
import java.io.File ;
import java.io.OutputStream ;
import java.io.FileOutputStream ;
public class OutputStreamDemo03{
	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,true)  ;	// 此處表示在文件末尾追加內容
		// 第3步、進行寫操作
		String str = "Hello World!!!" ;		// 準備一個字符串
		byte b[] = str.getBytes() ;			// 隻能輸出byte數組,所以將字符串變為byte數組
		for(int i=0;i<b.length;i++){		// 采用循環方式寫入
			out.write(b[i]) ;	// 每次隻寫入一個內容
		}
		// 第4步、關閉輸出流
		out.close() ;						// 關閉輸出流
	}
};
程序本身是可以追加內容了,但是沒有換行,是直接追加到末尾的。
如果在文件中想換行的話,使用“\r\n”完成。
import java.io.File ;
import java.io.OutputStream ;
import java.io.FileOutputStream ;
public class OutputStreamDemo04{
	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,true)  ;	// 此處表示在文件末尾追加內容
		// 第3步、進行寫操作
		String str = "\r\nHello World!!!" ;		// 準備一個字符串
		byte b[] = str.getBytes() ;			// 隻能輸出byte數組,所以將字符串變為byte數組
		for(int i=0;i<b.length;i++){		// 采用循環方式寫入
			out.write(b[i]) ;	// 每次隻寫入一個內容
		}
		// 第4步、關閉輸出流
		out.close() ;						// 關閉輸出流
	}
};

3.2字節輸入流InputStream



import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo01{
	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] ;		// 所有的內容都讀到此數組之中
		input.read(b) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流
		System.out.println("內容為:" + new String(b)) ;	// 把byte數組變為字符串輸出
	}
};
功能雖然實現了,但是存在問題? 數據的長度、數組的空間。
import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo02{
	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 = input.read(b) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流\
		System.out.println("讀入數據的長度:" + len) ;
		System.out.println("內容為:" + new String(b,0,len)) ;	// 把byte數組變為字符串輸出
	}
};


import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo03{
	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[(int)f.length()] ;		// 數組大小由文件決定
		int len = input.read(b) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流\
		System.out.println("讀入數據的長度:" + len) ;
		System.out.println("內容為:" + new String(b)) ;	// 把byte數組變為字符串輸出
	}
};
import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo04{
	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[(int)f.length()] ;		// 數組大小由文件決定
		for(int i=0;i<b.length;i++){
			b[i] = (byte)input.read() ;		// 讀取內容
		}
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流\
		System.out.println("內容為:" + new String(b)) ;	// 把byte數組變為字符串輸出
	}
};
以上的操作隻適合於知道輸入流的大小,如果現在不知道輸入流大小。
import java.io.File ;
import java.io.InputStream ;
import java.io.FileInputStream ;
public class InputStreamDemo05{
	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數組變為字符串輸出
	}
};
當不知道讀取內容多大的時候,可以使用讀取內容返回值為-1 為讀完的標誌。

4、字符流


4.1字符輸出流Writer



字符流的操作比字節流操作好在一點,就是可以直接輸出字符串了。不用再進行轉換操作了。
import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
public class WriterDemo01{
	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.close() ;						// 關閉輸出流
	}
};
使用字符流默認情況下依然是覆蓋已有的文件,如果想要追加的話,則直接在FileWriter上增加一個可追加的標記即可。
import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
public class WriterDemo02{
	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,true)  ;	// 通過對象多態性,進行實例化
		// 第3步、進行寫操作
		String str = "\r\nLIXINGHUA\r\nHello World!!!" ;		// 準備一個字符串
		out.write(str) ;						// 將內容輸出,保存文件
		// 第4步、關閉輸出流
		out.close() ;						// 關閉輸出流
	}
};

4.2字符輸入流Reader



以字符數組的形式讀取數據:
import java.io.File ;
import java.io.Reader ;
import java.io.FileReader ;
public class ReaderDemo01{
	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 len = input.read(c) ;		// 讀取內容
		// 第4步、關閉輸出流
		input.close() ;						// 關閉輸出流
		System.out.println("內容為:" + new String(c,0,len)) ;	// 把字符數組變為字符串輸出
	}
};
采用循環的方式,通過文件是否讀到低的形式讀取:
import java.io.File ;
import java.io.Reader ;
import java.io.FileReader ;
public class ReaderDemo02{
	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)) ;	// 把字符數組變為字符串輸出
	}
};

5、字節流與字符流的區別


驗證字符流使用了緩存:
import java.io.File ;
import java.io.OutputStream ;
import java.io.FileOutputStream ;
public class OutputStreamDemo05{
	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() ;						// 關閉輸出流
	}
};
在使用字節流操作中,及時沒有關閉,最終也是可以輸出的。
import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
public class WriterDemo03{
	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.close() ;						// 此時,沒有關閉
	}
};
import java.io.File ;
import java.io.Writer ;
import java.io.FileWriter ;
public class WriterDemo04{
	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() ;						// 此時,沒有關閉
	}
};

6、操作範例



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() ;
			}
		}
	}	
}

最後更新:2017-04-03 14:53:53

  上一篇:go <font color="red">[置頂]</font>
  下一篇:go Linux內核--usb子係統的分析