1. 程式人生 > >Java基礎知識複習(五)-- 位元組流 && 字元流

Java基礎知識複習(五)-- 位元組流 && 字元流

一、位元組流

InputStream位元組輸入流 ,OutputStream位元組輸出流 ,用於以位元組的形式讀取和寫入資料
所有的資料存放在計算機中都是以數字的形式存放的。 所以字母就需要轉換為數字才能夠存放。
比如A就對應的數字65,a對應的數字97. 不同的字母和符號對應不同的數字,就是一張碼錶。
ASCII是這樣的一種碼錶。 只包含簡單的英文字母,符號,數字等等。

參考程式碼

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;

import javax.imageio.stream.FileImageInputStream;

public class TestFile {
	  
    public static void main(String[] args) throws IOException {
    	File f = new File("d:/Test1/1.txt");
    	File f1 = new File("d:/Test1/2.txt");
    	//建立父資料夾
    	f.getParentFile().mkdirs();
    	//建立1.txt,2.txt檔案
    	f.createNewFile();
    	f1.createNewFile();
//    	把流定義在try()裡,try,catch或者finally結束的時候,會自動關閉
//    	這種編寫程式碼的方式叫做 try-with-resources, 這是從JDK7開始支援的技術
//    	所有的流,都實現了一個介面叫做 AutoCloseable,任何類實現了這個介面,都可以在try()中進行例項化,
//    	並且在try, catch, finally結束的時候自動關閉,回收相關資源。

    	try(FileInputStream FIS = new FileInputStream(f);
    		FileInputStream FIS1 = new FileInputStream(f1);
    		FileOutputStream FOS = new FileOutputStream(f);
    		FileOutputStream FOS1 = new FileOutputStream(f1);){
			byte[] data = {'a','A'};
			byte[] all = new byte[(int) data.length];
			byte[] all1 = new byte[(int) data.length];
			//將data入寫1.txt
			FOS.write(data);
			//讀1.txt
			FIS.read(all);
			//將1.txt的內容寫到2.txt
			FOS1.write(all);
			//讀2.txt
			FIS1.read(all1);
			
			for(byte a : all1) {
				System.out.println((char)a);			
			}
			
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
		}
    	
    	//列印父資料夾中所有的檔案
    	File[] r = f.getParentFile().listFiles();
    	for(File s : r){
    		System.out.println(s);
    	} 	
       
    }
}

執行結果
在這裡插入圖片描述
控制檯輸出
在這裡插入圖片描述

二、字元流

Reader字元輸入流
Writer字元輸出流
專門用於字元的形式讀取和寫入資料

參考程式碼

package review4;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestStream {
	public static void main(String[] args) throws IOException {
		File f = new File("D:/Test/3.txt");
		//建立Test資料夾
		f.getParentFile().mkdirs();
		//建立3.txt檔案
		f.createNewFile();
		
		try (FileWriter fw = new FileWriter(f)){
			String s = "abcdefg";
			//將字串s寫進3.txt檔案中
			char[] write = s.toCharArray();
			fw.write(write);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try (FileReader fr = new FileReader(f)){
				//從3.txt中讀出資料
				char[] read = new char[(int) f.length()];
				System.out.println(f.length());
				fr.read(read);
				for(char r : read) {
					System.out.print(r+"\t");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
}

執行結果
在這裡插入圖片描述
控制檯輸出
在這裡插入圖片描述

三、用FileInputStream 位元組流正確讀取中文

為了能夠正確的讀取中文內容必須瞭解文字是以哪種編碼方式儲存字元的, 使用位元組流讀取了文字後,再使用對應的編碼方式去識別這些數字,得到正確的字元

參考程式碼

package review4;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class TestStream {
		 public static void main(String[] args) throws IOException {
		        File f = new File("d:Test/test.txt");
		        try (FileInputStream fis = new FileInputStream(f);) {
		            byte[] all = new byte[(int) f.length()];
		            fis.read(all);
		   
		            //檔案中讀出來的資料是
		            System.out.println("檔案中讀出來的資料是:");
		            for (byte b : all)
		            {
		                int i = b&0x000000ff;  //只取16進位制的後兩位
		                System.out.println(Integer.toHexString(i));
		            }
		            System.out.println("把這個數字,放在GBK的棋盤上去:");
		            String str = new String(all,"GBK");
		            System.out.println(str);
		        } catch (IOException e) {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        }
		   
		    }
}

執行結果
在這裡插入圖片描述

四、用FileReader 字元流正確讀取中文

FileReader得到的是字元,所以一定是已經把位元組根據某種編碼識別成了字元了
而FileReader使用的編碼方式是Charset.defaultCharset()的返回值,如果是中文的作業系統,就是GBK
FileReader是不能手動設定編碼方式的,為了使用其他的編碼方式,只能使用InputStreamReader來代替,比如:new InputStreamReader(new FileInputStream(f),Charset.forName(“UTF-8”));

在本例中,用記事本另存為UTF-8格式,然後用UTF-8就能識別對應的中文。

解釋: 為什麼中字前面有一個?
如果是使用記事本另存為UTF-8的格式,那麼在第一個位元組有一個標示符,叫做BOM用來標誌這個檔案是用UTF-8來編碼的。

參考程式碼

package review4;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

public class TestStream {
		 public static void main(String[] args) throws IOException {
		        File f = new File("d:Test/test1.txt");
		        System.out.println("預設的編碼方式:"+Charset.defaultCharset());
		        //FileReader得到的是字元,所以一定是已經把位元組根據某種編碼識別成了字元了
		        //而FileReader使用的編碼方式是Charset.defaultCharset()的返回值,如果是中文的作業系統,就是GBK
		        try (FileReader fis = new FileReader(f);) {
		            char[] all = new char[(int) f.length()];
		            fis.read(all);
		            System.out.printf("FileReader會使用預設的編碼方式%s,識別出來的字元是:%n",Charset.defaultCharset()); 
		            System.out.println(new String(all));
		        } catch (IOException e) {
		            // TODO Auto-generated catch block
		            e.printStackTrace();
		        }
		        //FileReader是不能手動設定編碼方式的,為了使用其他的編碼方式,只能使用InputStreamReader來代替
		        //並且使用new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8")); 這樣的形式
		        try(InputStreamReader isr = new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"))) {
		        	char[] all = new char[(int) f.length()];
		        	isr.read(all);
		        	 System.out.printf("InputStreamReader 指定編碼方式UTF-8,識別出來的字元是:%n");
		             System.out.println(new String(all));
				} catch (Exception e) {
					// TODO: handle exception
				}
		   
		    }
}

執行結果
在這裡插入圖片描述