Java I/O(輸入/輸出)是Java語言中用於處理資料流的一套豐富而強大的API。Java I/O分為兩個主要的包:java.io
和java.nio
(非阻塞I/O)。以下是一些Java I/O的基本概念和元件:
1. 流的概念
- 流:是位元組序列的表示,可以是輸入流(讀取資料)或輸出流(傳送資料)。
2. 主要的流類
- InputStream 和 OutputStream:所有輸入流的超類和所有輸出流的超類。
- Reader 和 Writer:基於字元的輸入/輸出流的超類,使用字符集進行編碼和解碼。
3. 位元組流
- FileInputStream:從檔案中讀取位元組。
- FileOutputStream:向檔案寫入位元組。
- ByteArrayInputStream 和 ByteArrayOutputStream:記憶體中的位元組陣列輸入/輸出。
4. 字元流
- FileReader 和 FileWriter:從檔案讀取字元和向檔案寫入字元。
- CharArrayReader 和 CharArrayWriter:記憶體中的字元陣列輸入/輸出。
5. 緩衝流
- BufferedInputStream 和 BufferedOutputStream:提供緩衝以提高讀寫效率。
- BufferedReader 和 BufferedWriter:提供緩衝以提高字元讀寫效率。
6. 資料流
- DataInputStream:從底層的InputStream中讀取資料,並將其轉換為Java原始資料型別。
- DataOutputStream:將Java原始資料型別轉換為可以由InputStream讀取的位元組。
7. 物件流
- ObjectInputStream 和 ObjectOutputStream:允許物件的讀寫。
8. 列印流
- PrintStream 和 PrintWriter:提供方便的列印方法。
9. 隨機訪問檔案
- RandomAccessFile:可以以讀、寫或二者兼備的模式開啟檔案,並可以隨機訪問檔案。
10. 管道流
- PipedInputStream 和 PipedOutputStream:允許執行緒透過管道進行通訊。
11. 檔案操作
- File:表示檔案和目錄路徑名,提供檔案操作方法。
示例程式碼
以下是使用Java I/O進行檔案讀寫的基本示例:
import java.io.*;
public class IOExample {
public static void main(String[] args) {
String filePath = "example.txt";
// 寫入文字到檔案
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
writer.write("Hello, Java I/O!");
} catch (IOException e) {
e.printStackTrace();
}
// 從檔案讀取文字
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意事項
- 使用
try-with-resources
語句自動管理資源,確保Closeable
物件在使用後能夠正確關閉。 - 捕獲並處理
IOException
,因為I/O操作可能會引發此類異常。 - 根據需要選擇合適的流型別,比如位元組流或字元流。
Java I/O是Java SE的核心部分,對於任何需要處理檔案或資料流的Java應用程式來說都是必不可少的。
以下是Java I/O中不同型別流的使用示例:
1. 位元組流 - FileInputStream 和 FileOutputStream
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamExample {
public static void main(String[] args) {
String fromFile = "source.txt";
String toFile = "destination.txt";
try (FileInputStream fis = new FileInputStream(fromFile);
FileOutputStream fos = new FileOutputStream(toFile)) {
int byteRead;
while ((byteRead = fis.read()) != -1) {
fos.write(byteRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 字元流 - FileReader 和 FileWriter
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharStreamExample {
public static void main(String[] args) {
String fromFile = "source.txt";
String toFile = "destination.txt";
try (FileReader fr = new FileReader(fromFile);
FileWriter fw = new FileWriter(toFile)) {
int charRead;
while ((charRead = fr.read()) != -1) {
fw.write(charRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 緩衝流 - BufferedReader 和 BufferedWriter
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedStreamExample {
public static void main(String[] args) {
String inputFile = "input.txt";
String outputFile = "output.txt";
try (BufferedReader br = new BufferedReader(new FileReader(inputFile));
BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine(); // 寫入一個新行
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 資料流 - DataInputStream 和 DataOutputStream
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataStreamExample {
public static void main(String[] args) {
String dataFile = "data.txt";
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(dataFile))) {
dos.writeInt(123);
dos.writeDouble(45.67);
} catch (IOException e) {
e.printStackTrace();
}
try (DataInputStream dis = new DataInputStream(new FileInputStream(dataFile))) {
int intValue = dis.readInt();
double doubleValue = dis.readDouble();
System.out.println("Int: " + intValue + ", Double: " + doubleValue);
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. 物件流 - ObjectOutputStream 和 ObjectInputStream
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.Serializable;
public class ObjectStreamExample {
public static void main(String[] args) {
String objectFile = "object.dat";
MyObject obj = new MyObject("Data", 123);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(objectFile))) {
oos.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(objectFile))) {
MyObject objRead = (MyObject) ois.readObject();
System.out.println("Object read: " + objRead);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
static class MyObject implements Serializable {
private String data;
private int number;
public MyObject(String data, int number) {
this.data = data;
this.number = number;
}
@Override
public String toString() {
return "MyObject{" +
"data='" + data + '\'' +
", number=" + number +
'}';
}
}
}
6. 隨機訪問檔案 - RandomAccessFile
import java.io.RandomAccessFile;
import java.io.IOException;
public class RandomAccessFileExample {
public static void main(String[] args) {
String file = "random.dat";
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
// 寫入資料
raf.writeInt(12345);
raf.writeDouble(67.89);
// 移動檔案指標到檔案開頭
raf.seek(0);
// 讀取資料
int intValue = raf.readInt();
double doubleValue = raf.readDouble();
System.out.println("Int: " + intValue + ", Double: " + doubleValue);
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意事項
- 所有示例都使用了
try-with-resources
語句來自動關閉資源。 - 這些示例中的檔案路徑、資料型別和資料值僅為示例,你應該根據實際需求進行調整。
- 對於
ObjectOutputStream
和ObjectInputStream
,物件必須實現Serializable
介面。 - 異常處理使用了
e.printStackTrace()
,僅用於示例。在實際應用中,你可能需要更精細的異常處理策略。