java學習之字符流和字節流的區別

一、字節輸出流OutputStream

  1. OutputStream是抽象類,是表示輸出字節流的所有超類,操作的數據都是字節,定義了字節輸出流的基本共性和方法。OutputStream有大量子類,具體請看javaAPI文檔,比較常用的是FileOutputStream 即:將數據寫入到File的輸出流。

    注意:其中的方法close()方法和Flush()方法的不同,close()自帶flush()方法,但是close()一旦使用就會關閉和釋放該流的所有資源,即這個流不能再使用了。flush()則是強制寫出所有緩衝的所有字節,即將數據強制從緩衝中寫入到文檔中。

  2. FileOutputStream有哪些用處

    1、可以往指定的文件裏寫東西.
    2、可以給文檔內容進行續寫和換行處理,換行符爲\r\n添加字符的前面

  3. FileOutputStream需要IO異常處理

    1、因爲FileOutStream是往文檔裏寫數據的,必須指定相應的文檔,如果這個文檔不存在怎麼辦?那就要拋異常了。
    2、處理異常有兩種方式,一是直接拋出throws IOException,另一種是使用try…catch…finally的方式。

    
    		public class FileOutputStreamDemo3 {
    			public static void main(String[] args) {
    				//將路徑名賦給file文件,這裏並沒有創建file.txt,只是將這個路徑給File
    				File file = new File("c:\\file.txt");
    				//定義FileOutputStream的引用
    				FileOutputStream fos = null;
    				try {
    					//創建FileOutputStream對象
    					fos = new FileOutputStream(file);
    					//寫出數據
    					fos.write("abcde".getBytes());
    				} catch (IOException e) {
    					System.out.println(e.toString() + "----");
    				} finally {
    					//一定要判斷fos是否爲null,只有不爲null時,纔可以關閉資源
    					if (fos != null) {
    						try {
    							fos.close();
    						} catch (IOException e) {
    							//如果爲空,拋出異常
    							throw new RuntimeException("");
    						}
    					}
    				}
    			}
    		}
    
    	
    
  4. OutputStream字節輸出流和File類的區別:

    區別有:
    1、File類是針對文件路徑的,有以下功能,可以創建刪除一個文件,可以對文件進行copy,可以調取文件的路徑,文件名,文件大小,可以將路徑下的所有文件放到一個數組裏面,可見File類就是對文件和路徑的操作,如果往文檔裏插入一些內容或續寫一些數據是不行的。
    2、OutputStream是對文檔的操作,專門用於向文檔裏輸入數據的。

#二、字節輸入流InputStream

  1. OutputStream是將內存中的數據寫出到文件中,而InputStream的作用是將文件中的數據讀入到內存中。InputStream和OutputStream正好相對應,前者是將文件中的數據讀入到內存中,後者是將內存中的數據寫入文件中。也有子類FileInputStream

    注意:FileInputStream有兩個讀取文件內容的方法,一個是read(),另一個是read(byte[] b),前者是一個字節一個字節的讀取,後者是一個數組一個數組的讀取當然後者的速度更快。但是這裏有個小問題,看代碼:

    
    	public class FileInputStreamDemo {
    		public static void main(String[] args) throws IOException {
    			File file = new File("c:\\file.txt");
    			//創建一個字節輸入流對象,必須明確數據源,其實就是創建字節讀取流和數據源相關聯。
    			FileInputStream fis = new FileInputStream(file);
    			//讀取數據。使用 read();一次讀一個字節。
    			int ch = 0;
    			while((ch=fis.read())!=-1){
    				System.out.println("ch="+(char)ch);
    	
    			// 關閉資源。
    			fis.close();
    		}
    	}
    
    

    下面是用read(byte[] b)方法讀取的

    
    			public class FileInputStreamDemo2 {
    				public static void main(String[] args) throws IOException {
    					/*
    					 * 演示第二個讀取方法, read(byte[]);
    					 */
    					File file = new File("c:\\file.txt");
    					// 創建一個字節輸入流對象,必須明確數據源,其實就是創建字節讀取流和數據源相關聯。
    					FileInputStream fis = new FileInputStream(file);		
    					//創建一個字節數組。
    					byte[] buf = new byte[1024];//長度可以定義成1024的整數倍。		
    					int len = 0;
    					while((len=fis.read(buf))!=-1){
    						System.out.println(new String(buf,0,len));
    					}
    					fis.close();
    				}
    			}
    		
    

    兩者的區別是:read()的方法一次只讀一個字節並且返回的是一個編碼數字,而read(byte[] b)一次讀取數組大小字節,然後再打印這個數組

#三、字符流Reader和Writer

  1. Reader

    Reader是抽象類,Reader的直接子類有InputStreamReader,它的直接子類有FileReader.這表明Reader是字符輸入流的祖宗類。

  2. Writer

    Writer是抽象類,Writer的直接子類有OutputStreamWriter,它的直接子類有FileWriter.這表明Writer字符輸出流的子類。

#四、字符流和字節流的區別:

  1. 字節流是以字節爲單位傳遞的,因爲所有電腦上的東西都是二進制字節,因此可以傳遞任何數據,比如圖片,各種字符等。字節流只能寫入字節,讀取字節。windows中的默認編碼是AscII編碼,當你用字節流寫入某個文檔時只能先轉換成ASCII編碼,然後再寫入文檔,當你去查看文檔時windows系統默認用ASCII編碼將其解碼,你才能看懂裏面的內容。實際上存儲的都是字節編碼。當用讀取文件內容時,FileReader類也是讀取的是字符編碼。這就造成了當你用FileReader讀取文件內容時讀取的內容時數字。例如下面這段代碼:

    
    	public class CharStreamDemo {
    		public static void main(String[] args) throws IOException {
    			//給文件中寫中文
    			writeCNText();
    			//讀取文件中的中文
    			readCNText();
    		}	
    		//讀取中文
    		public static void readCNText() throws IOException {
    			FileInputStream fis = new FileInputStream("c:\\cn.txt");
    			int ch = 0;
    			//此處的read()函數讀取的是字節,打印出來的是ASCII碼
    			while((ch = fis.read())!=-1){
    				System.out.println(ch);
    			}
    		}
    		//寫中文
    		public static void writeCNText() throws IOException {
    			FileOutputStream fos = new FileOutputStream("c:\\cn.txt");
    			//注意此處write是將字符串內容轉換成字節後寫入的,如果不轉換成字節數組,是不能寫的。
    			fos.write("a中華民族歡迎你".getBytes());
    			fos.close();
    		}
    	}
    
    

    可見字節流是通過字節碼的方式讀取和輸入的。必須通過字節碼的形式進行寫入和讀取。

  2. 字符流的運用

    加入有一個文本文檔裏面存儲的是字節碼,你要打印裏面的內容,也就是讀取到控制檯上,你總不能用FileOutputStream打印幾個ASCII碼數字吧,這時候就需要用到FileWriter字符流了,FileReader的默認編碼是gbk.比如這段代碼:

    
    		public class CharStreamDemo {
    			public static void main(String[] args) throws IOException {
    				//給文件中寫中文
    				writeCNText();
    				//讀取文件中的中文
    				readCNText();
    			}	
    			//讀取中文
    			public static void readCNText() throws IOException {
    				//讀取的是通過FileReader類讀取的,讀取的是字符流,字符流的方法
    				FileReader fr = new FileReader("D:\\test\\cn.txt");
    				int ch = 0;
    				while((ch = fr.read())!=-1){
    					//輸出的字符對應的編碼值
    					System.out.println(ch);
    					//輸出字符本身
    					System.out.println((char)ch);
    				}
    			}
    			//寫中文
    			public static void writeCNText() throws IOException {
    				//通過FileOutputStream寫入的是字節編碼,文檔裏存儲的是字節碼
    				FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
    				fos.write("a中華民族歡迎你".getBytes());
    				fos.close();
    			}
    		}  
    
    
    

    3 . 字符流和字節流的最大區別就是,

    字節流FileInputStream讀取方法read()是一個字節一個字節的讀取,Write()方法是一個字節一個字節的寫入。在gbk當中一個漢字佔用2個字節,utf-8中一個漢字佔用3個字節,如果一個字節一個字節的讀讀出來的編碼無法組成一個漢字。而如果用字符流,去讀取,字符流會根據默認編碼一次性的讀取一個字符,即若是utf-8編碼就會讀取3字節,若是gbk編碼就會一次讀取2個字節。因此字符流是根據字符所佔字節大小而決定讀取多少字節的。這就是字符流和字節流的本質不同。

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