1. 程式人生 > 其它 >Java 程式設計基礎——IO常用類

Java 程式設計基礎——IO常用類

技術標籤:隨筆記錄Java學習java

Java IO流 常用類

菜鳥教程

檔案流

  1. FileInputStream / FileOutputStream 位元組流
  2. FileReader/FileWriter 字元流
package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class TestIO { public static void FileInputStreamTest() { FileInputStream fis = null; try{ //注意:本地需先有一個tmp2.txt檔案 fis = new FileInputStream("tmp2.txt"); byte[] buf = new byte[1024]; int hasRead = 0; //fis.read()返回的是單個位元組資料(位元組資料可以直接轉為int型別),
//而fis.read(buf)返回讀取的位元組數,資料儲存在buf中 while ((hasRead = fis.read(buf)) > 0) { //每次最多將1024個位元組轉換成字串,這裡tmp2.txt中的字元小於1024,所以一次就讀完了 //迴圈次數 = 檔案字元數 除以 buf長度 System.out.println(new String(buf, 0 ,hasRead)); /* 將位元組強制轉換成字元後逐個輸出,能實現和上面一樣的效果。 但是如果原始檔是中文的話可能會亂碼 【這裡是多次迴圈,把buf的每個值賦值給b,然後將位元組b轉為字元】 for (byte b : buf) { char ch = (char)b; if (ch != '\r') System.out.print(ch); } */
} } catch(IOException e){ e.printStackTrace(); } finally{ try { if (ifs != null) ifs.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void FileReaderTest() throws IOException { try ( // 在try() 中開啟的檔案, JVM會自動關閉 FileReader fr = new FileReader("tmp2.txt")) { char[] buf = new char[32]; int hasRead = 0; // 每個char都佔兩個位元組,每個字元或者漢字都是佔2個位元組, //因此無論buf長度為多少,總是能讀取中文字元長度的整數倍,不會亂碼 while ((hasRead = fr.read(buf)) > 0) { // 如果buf的長度大於檔案每行的長度,就可以完整輸出每行,否則會斷行。 // 迴圈次數 = 檔案字元數 除以 buf長度 System.out.println(new String(buf, 0, hasRead)); // 跟上面效果一樣 // System.out.println(buf); } } catch (IOException ex) { ex.printStackTrace(); } } public static void FileOutputStreamTest() throws FileNotFoundException, IOException { try ( //在try()中開啟檔案會在結尾自動關閉 FileInputStream fis = new FileInputStream("tmp2.txt"); FileOutputStream fos = new FileOutputStream("tmp3.txt"); ) { byte[] buf = new byte[4]; int hasRead = 0; while ((hasRead = fis.read(buf)) > 0) { //每讀取一次就寫一次,讀多少就寫多少 fos.write(buf, 0, hasRead); } System.out.println("write success"); } catch (IOException e) { e.printStackTrace(); } } public static void FileWriterTest() throws IOException { try (FileWriter fw = new FileWriter("tmp4.txt")) { fw.write("天王蓋地虎\r\n"); fw.write("寶塔鎮河妖\r\n"); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { //FileInputStreamTest(); //FileReaderTest(); //FileOutputStreamTest(); FileWriterTest(); } }

緩衝流

  1. BufferedReader / BufferedWriter 針對字元
  2. BufferedInputStream / BufferedOutputStream 針對位元組
  • 沒有經過Buffered處理的IO,意味著每一次讀和寫的請求都會由OS底層直接處理,這會導致非常低效的問題。

  • 經過Buffered處理過的輸入流將會從一個buffer記憶體區域讀取資料,本地API只會在buffer空了之後才會被呼叫(可能一次呼叫會填充很多資料進buffer)。

  • 經過Buffered處理過的輸出流將會把資料寫入到buffer中,本地API只會在buffer滿了之後才會被呼叫。

​ BufferedReader/BufferedWriter可以將字元流(Reader)包裝成緩衝流,這是最常見用的做法。

​ 另外,BufferedReader提供一個readLine()可以方便地讀取一行,而FileInputStream和FileReader只能讀取一個位元組或者一個字元,

​ 因此BufferedReader也被稱為行讀取器。

轉換流

  1. InputStreamReader
  2. OutputStreamReader

​ 這兩個類可以將位元組流轉換成字元流,被稱為位元組流與字元流之間的橋樑。我們經常在讀取鍵盤輸入(System.in)或網路通訊的時候,需要使用這兩個類。

下面演示上面上面常見類

package io;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PushbackReader;
import java.io.StringReader;
import java.io.StringWriter;

public class TestIO {
    public static void keyIn() throws IOException {
        try {
            //InputStreamReader是從byte轉成char的橋樑
            InputStreamReader reader = new InputStreamReader(System.in);
            //BufferedReader(Reader in)是字元型別輸入的包裝類
            BufferedReader br = new BufferedReader(reader);
            String line = null;
            while ((line = br.readLine()) != null) {
                if (line.equals("exit")) {
                    //System.exit(1);
                    break;
                }
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws IOException {
        keyIn();
    }
}

位元組陣列輸出流

ByteArrayOutputStream 在記憶體中建立一個位元組緩衝區, 所有傳送到輸出流的資料儲存在該位元組陣列緩衝區中,緩衝區會隨著不斷寫入而增長,可使用toByteArray()和toString()獲取資料。主要用來接受資料,然後再一次性將資料輸出。

下面有兩種方式建立物件:

ByteArrayOutputStream bOut = new ByteArrayOutputStream();//預設32位元組的緩衝區
ByteArrayOutputStream bOut = new ByteArrayOutputStream(int a);//a位元組的緩衝區

演示

public static void main(String[] args) throws IOException {
		FileInputStream fos = new FileInputStream("D:" + File.separator + "temp.out");
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
    	byte[] buffer = new byte[1024];
    	int len;
    	//從檔案裡讀取的臨時資料存入buffer中
		while((len = fos.read(buffer))!=-1){//len是每次讀取檔案後,buffer的長度
            baos.wraite(buffer, 0, len);//每次讀取後都將buffer中的資料寫入baos中
        }
    	System.out.println(baos.toString());//將baos中的資料一次性打印出來
    	baos.close();
		fos.close();
	}