Java 程式設計基礎——IO常用類
阿新 • • 發佈:2021-01-20
Java IO流 常用類
檔案流
- FileInputStream / FileOutputStream 位元組流
- 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();
}
}
緩衝流
- BufferedReader / BufferedWriter 針對字元
- BufferedInputStream / BufferedOutputStream 針對位元組
-
沒有經過Buffered處理的IO,意味著每一次讀和寫的請求都會由OS底層直接處理,這會導致非常低效的問題。
-
經過Buffered處理過的輸入流將會從一個buffer記憶體區域讀取資料,本地API只會在buffer空了之後才會被呼叫(可能一次呼叫會填充很多資料進buffer)。
-
經過Buffered處理過的輸出流將會把資料寫入到buffer中,本地API只會在buffer滿了之後才會被呼叫。
BufferedReader/BufferedWriter可以將字元流(Reader)包裝成緩衝流,這是最常見用的做法。
另外,BufferedReader提供一個readLine()可以方便地讀取一行,而FileInputStream和FileReader只能讀取一個位元組或者一個字元,
因此BufferedReader也被稱為行讀取器。
轉換流
- InputStreamReader
- 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();
}