Java IO學習筆記(一) —— IO基礎
Java IO 流學習筆記
1 什麼是流
記憶體與儲存設備之間傳輸資料的通道。
2 流的分類
2.1 按方向
- 輸入流:将儲存設備中的内容讀取到記憶體中;
- 輸出流:将記憶體中的内容寫入到儲存設備中。
2.2 按機關
- 位元組流:以位元組為機關,可以讀取所有資料;
- 字元流:以字元為機關,隻能讀取文本資料。
位元組(Byte)是計量機關,表示資料量多少,是計算機資訊技術用于計量存儲容量的一種計量機關,通常情況下一位元組等于八位。
字元(Character)計算機中使用的字母、數字、字和符号,比如’A’、‘B’、’$’、’&'等。
2.3 按功能
- 節點流:具有實際傳輸資料的讀寫功能;
- 過濾流:在節點流的基礎之上增強的功能。
3 位元組流抽象類
-
InputStream
這個抽象類是表示輸入位元組流的所有類的超類。
需要定義InputStream子類的應用InputStream必須始終提供一種傳回輸入的下一個位元組的方法。
-
OutputStream
這個抽象類是表示位元組輸出流的所有類的超類。 輸出流接收輸出位元組并将其發送到某個接收器。
需要定義OutputStream子類的應用OutputStream必須至少提供一個寫入一個位元組輸出的方法。
4.檔案輸入輸出流
4.1 FileInputStream輸入流
(1) read() 單位元組讀取
/**
* 單位元組讀取
* read(): 從該輸入流讀取下一個資料位元組
* @param filePath
*/
public static void demo1(String filePath){
try(FileInputStream fileInputStream = new FileInputStream(filePath)){
int data;
while ((data = fileInputStream.read()) != -1){
System.out.print((char) data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
(2)read(byte[] b) 一次讀取多個位元組
/**
* 一次讀取多個位元組
*
* read(byte[] b):從該輸入流讀取最多 byte.length個位元組的資料到位元組數組。
* @param filePath
*/
public static void demo2(String filePath){
try(FileInputStream fileInputStream = new FileInputStream(filePath)){
byte[] buf = new byte[3]; // 大小為3的緩存區
int count = 0;
while((count = fileInputStream.read(buf)) != -1){
System.out.println(new String(buf, 0, count));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
(3) read(byte[] b, int off, int len)
/**
*一次讀取多個位元組
*
* read(byte[] b, int off, int len)
* 從該輸入流讀取最多 len位元組的資料到位元組數組。
* @param filePath
*/
public static void demo3(String filePath){
try(FileInputStream fileInputStream = new FileInputStream(filePath)){
byte[] buf = new byte[3]; // 大小為3的緩存區
int count = 0;
while((count = fileInputStream.read(buf,0,buf.length)) != -1){
System.out.println(new String(buf, 0, count));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4.2 FileOutputStream檔案輸出流
public class FileOutputStreamDemo {
public static void main(String[] args) {
String filePath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ccc.txt";
try(FileOutputStream out = new FileOutputStream(filePath)){
out.write("hello word!".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.3 檔案輸入輸出流案例
public class FileCopyDemo {
public static void main(String[] args) {
// 1.建立流,檔案輸入流,檔案輸出流
String orgPath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ccc.txt";
String tarPath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ddd.txt";
try (
FileInputStream in = new FileInputStream(orgPath);
FileOutputStream out = new FileOutputStream(tarPath);
) {
// 2 邊讀邊寫
byte[] buf = new byte[1024];
int count = 0;
while ((count = in.read(buf)) != -1) {
out.write(buf, 0, count);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5 位元組緩沖流
緩沖流:BufferedInputStream/ BufferedOutputStream
- 提高IO效率,減少通路磁盤次數
- 資料存儲在緩沖區中,flush是将緩沖區的内容寫入檔案中,也可以直接close
5.1 BufferedInputStream
public class BufferedInputStreamDemo {
public static void main(String[] args) {
String filePath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/ccc.txt";
try (
FileInputStream fis = new FileInputStream(filePath);
BufferedInputStream bis = new BufferedInputStream(fis)
) {
// 2 讀取
int data = 0;
while ((data = bis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.2 BufferedOutputStream
public class BufferedOutputStreamDemo {
public static void main(String[] args) {
String tarPath = "/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/eee.txt";
try (
FileOutputStream fos = new FileOutputStream(tarPath);
BufferedOutputStream bos = new BufferedOutputStream(fos)
) {
// 寫入檔案
for (int i = 0; i < 10; i++) {
bos.write("hello".getBytes());// 寫入8k緩沖區
bos.flush(); // 重新整理到硬碟
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
6 對象流
ObjectOutputStream / ObjectInputStream
- 增強了緩沖區功能
- 增強了讀寫8種基本資料類型和字元串的功能
-
增強了讀寫對象的功能
readObject() 從流中讀取一個對象
writeObject(Object obj) 向流中寫入一個對象
使用流傳輸對象的過程稱為序列化、反序列化
6.1 使用ObjectOutputStream實作對象的序列化
public class ObjectOutputStreamDemo {
public static void main(String[] args) {
// 1.建立對象流
try (
FileOutputStream fos = new FileOutputStream("/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/student.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos)
) {
// 2.序列化
Student student = new Student();
student.setAge(14);
student.setName("hello");
oos.writeObject(student);
} catch (IOException e) {
e.printStackTrace();
}
}
}
6.2 使用ObjectInputStream實作對象的反序列化
public class ObjectInputStreamDemo {
public static void main(String[] args) {
try (
FileInputStream fis = new FileInputStream("/Users/pandamig/IdeaProjects/Study/IOStudy/src/main/resources/student.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
) {
Student stu = (Student) ois.readObject();
System.out.println(stu.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
6.3 注意事項
- 1.某個類要想序列化必須實作Serializable接口
- 2.序列化類中對象屬性要求實作Serializable接口
- 3.序列化版本号ID,保證序列化的類和反序列化的類是同一個類
- 4.使用transient修飾屬性,這個屬性就不能序列化
- 5.靜态屬性不能序列化
- 6.序列化多個對象,可以借助集合來實作