File類和IO流
File類
概述
- public class File
- 檔案和目錄路徑名的抽象表示
- 檔案和目錄是可以通過File封裝成物件的
- 封裝的不是檔案,而是一個路徑(可以存在,也可以不存在);要通過具體的操作將這個路徑轉化為具體存在
public class FileDemo {
public static void main(String[] args) {
//創建一個路徑操作物件 路徑包括父路徑和子路徑
File f = new File("G:\\FileTest\\java.txt");
System.out.println(f);
//創建一個路徑操作物件 父路徑,子路徑
File f1 = new File("G:\\FileTest","java.txt");
System.out.println(f1);
//創建一個父路徑操作物件
File f2 = new File("G:\\FileTest");
//從父路徑和子路徑創建的路徑操作物件
File f3 = new File(f2,"java.txt");
System.out.println(f3);
}
}
運行結果:
//File類重寫了toString()
G:\FileTest\java.txt
G:\FileTest\java.txt
G:\FileTest\java.txt
File類創建功能
運行代碼之前

代碼
public class FileDemo1 {
public static void main(String[] args) throws IOException {
/*在G:\FileTest目錄下,創建一個Hello.txt檔案
如果檔案不存在就創建檔案,回傳true
如果檔案存在回傳false*/
File f1 = new File("G:\\FileTest\\Hello.txt");
System.out.println(f1.createNewFile());
/*在G:\FileTest目錄下,創建一個Cat檔案夾
如果檔案不存在就創建檔案,回傳true
如果檔案存在回傳false*/
File f2 = new File("G:\\FileTest\\Cat");
System.out.println(f2.mkdir());
/*在G:\FileTest目錄下,創建一個多級目錄Eat\egg檔案夾
如果檔案不存在就創建檔案,回傳true
如果檔案存在回傳false*/
File f3 = new File("G:\\FileTest\\Eat\\egg");
System.out.println(f3.mkdirs());
}
}
運行結果
true
true
true


注意
- 如果同一目錄下存在同名的檔案夾,createNewFile()創建檔案時會失敗;要將同名的檔案夾刪掉才會創建檔案成功,
File類判斷和獲取功能

運行代碼之前,先在此位置創建一個java.txt檔案


public class FileDemo2 {
public static void main(String[] args) {
//創建File物件
File f = new File("idea_test\\java.txt");
//抽象路徑名表示的File是否為目錄
System.out.println("是否為目錄:"+f.isDirectory());
//抽象路徑名表示的File是否為檔案
System.out.println("是否為檔案:"+f.isFile());
//抽象路徑名表示的File是否存在
System.out.println("是否存在:"+f.exists());
//回傳此抽象路徑名的絕對路徑(字串)
System.out.println("絕對路徑:"+f.getAbsolutePath());
//將此抽象路徑名轉化為字串
System.out.println("抽象路徑:"+f.getPath());
//回傳此抽象路徑名表示的檔案名或者目錄名
System.out.println("檔案名或者目錄名:"+f.getName());
System.out.println("-------FileTest目錄-------------");
File f1 = new File("G:\\FileTest");
//回傳此抽象路徑名表示的目錄中的檔案名和目錄的名稱字串陣列
String[] list = f1.list();
//遍歷字串陣列
for (String s : list) {
System.out.println(s);
}
System.out.println("---------FileTest目錄中的檔案-----------");
//回傳此抽象路徑名表示的目錄中的檔案名和目錄的File物件陣列
File[] files = f1.listFiles();
for (File file : files) {
//System.out.println(file);
//如果物件是一個檔案,輸出檔案名
if (file.isFile()){
System.out.println(file.getName());
}
}
}
}
運行結果:
是否為目錄:false
是否為檔案:true
是否存在:true
絕對路徑:G:\Work_Basic\JavaSE_Code\idea_test\java.txt
抽象路徑:idea_test\java.txt
檔案名或者目錄名:java.txt
-------FileTest目錄-------------
Cat
Eat
Hello.txt
java.txt
---------FileTest目錄中的檔案-----------
Hello.txt
java.txt
File類洗掉功能

創建一個hello.txt檔案
public class FileDemo3 {
public static void main(String[] args) throws IOException {
//在當前模塊目錄下創建一個hello.txt檔案
File f = new File("idea_test\\hello.txt");
//System.out.println(f.createNewFile());
//洗掉當前模塊目錄下的hello.txt檔案
System.out.println(f.delete());
}
}
運行結果:hello.txt檔案已經洗掉
true

//在當前模塊目錄下創建一個"雀巢"檔案夾
File f1 = new File("idea_test\\雀巢");
System.out.println(f1.mkdir());
運行結果:true

//洗掉當前模塊目錄下的"雀巢"檔案夾
System.out.println(f1.delete());
運行結果:true

//在當前模塊目錄下創建一個"雀巢"檔案夾,檔案夾里有個java.txt檔案
File f2 = new File("idea_test\\雀巢");
System.out.println(f2.mkdir());
File f3 = new File(f2, "java.txt");
System.out.println(f3.createNewFile());
運行結果:
true
true

創建多級目錄檔案
- 在創建檔案之前,應該先創建上一級的目錄,否則會報錯
//洗掉當前模塊目錄下的"雀巢"檔案夾
System.out.println(f3.delete());
System.out.println(f2.delete());
運行結果:"雀巢"檔案夾刪掉了
true
true

洗掉檔案夾
- 如果要洗掉的檔案夾下有檔案,洗掉操作會不成功,回傳false
- 要先洗掉該檔案夾下的檔案,之后才能洗掉該檔案夾
遞回
方法中呼叫方法本身
思路:把一個復雜的問題,層層轉化為一個與原問題相似的規模較小的問題來求解,遞回策略只需少量的程式就可描述出解題程序所需要的多次重復計算,
public class Demo {
public static void main(String[] args) {
/*不死神兔:求第20個月兔子的對數
* 每個月兔子的對數:1,1,2,3,5,8……*/
//創建長度為20的陣列 索引0-19
int[] arr = new int[20];
//第一個月:1對
arr[0] = 1;
//第二個月:1對
arr[1] = 1;
//從第三個月(索引2)開始:兔子的對數等于前兩個月之和
for (int i = 2; i < arr.length; i++) {
arr[i] = arr[i - 1] + arr[i - 2];
}
//輸出第20個月(索引19)兔子的對數
System.out.println(arr[19]);
}
}
運行結果:
6765
使用遞回來解決上述問題
public class Demo {
public static void main(String[] args) {
/*不死神兔:求第20個月兔子的對數
* 每個月兔子的對數:1,1,2,3,5,8……*/
//第20個月,兔子的對數
System.out.println(f(20));
}
/**
* 遞回:求第n個月兔子的對數
*
* @param n 第n個月
* @return 兔子的對數
* StackOverflowError 當由于應用程式而發生堆疊溢位時引發 遞回太深,遞回需要停止
*/
public static int f(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
//從第3個月開始,每個月兔子的對數都是前兩個月之和
return f(n - 1) + f(n - 2);
}
}
}
運行結果:
6765
遞回解決問題
- 遞回出口:否則會出現記憶體溢位StackOverflowError
- 遞回規則:與原問題相似的規模較小的問題
案例:遞回求5的階乘
public class Demo {
public static void main(String[] args) {
//呼叫方法,求5的階乘
System.out.println(f(5));
}
/**
* 階乘
* @param n
* @return
*/
public static int f(int n) {
if (n == 1) {
return 1;
} else {
return n * f(n - 1);
}
}
}
運行結果:
120
IO位元組流
IO流概述
- IO:輸入/輸出
- 流:資料傳輸
- IO流就是處理設備之間資料傳輸問題的(常見:檔案復制,檔案上傳,檔案下載)
輸入:讀資料;硬碟到記憶體條
輸出:寫資料;記憶體條到硬碟
IO流的分類
- 按照資料的流向
- 輸入流:讀資料
- 輸出流:寫資料
- 按照資料型別
- 位元組流:位元組輸入流,位元組輸出流
- 字符流:字符輸入流,字符輸出流
使用場景
- 用記事本打開,能看懂的內容,使用字符流,否則使用位元組流,
- 如果不知道該使用哪種型別的流,就使用位元組流,
位元組流寫資料
位元組流抽象基類
- public abstract class InputStream:位元組輸入流的所有類的超類
- public abstract class OutputStream:位元組輸出流的所有類的超類
- 子類名稱特點:子類名稱都是以父類名作為子類命的后綴
FileOutputStream:檔案輸入流,用于將資料寫入File
- FileOutputStream(String name):將資料以指定的名稱寫入檔案
使用位元組輸出流寫資料的步驟
- 創建位元組輸出流物件
- 呼叫系統功能創建了檔案
- 創建位元組輸出流
- 讓位元組數流物件指向檔案)
- 呼叫位元組輸出流物件的寫資料方法
- 釋放資源:關閉此檔案的輸出流并釋放與此流關聯的任何系統資源
創建位元組輸出流物件的三種方式:
//創建位元組輸出流物件 第一種
FileOutputStream fo = new FileOutputStream("idea_test\\java.txt");
//創建位元組輸出流物件 第二種
File file = new File("idea_test\\java.txt");
FileOutputStream fo = new FileOutputStream(file);
//創建位元組輸出流物件 第三種
FileOutputStream fo = new FileOutputStream(new File("idea_test\\java.txt"));
案例:使用位元組輸出流寫資料的步驟
public class IoDemo {
public static void main(String[] args) throws IOException {
/**
* 創建位元組輸出流物件
* 1.呼叫系統功能創建了檔案
* 2.創建了位元組輸出流物件
* 3.讓位元組輸出流物件指向創建好的檔案
*/
FileOutputStream fo = new FileOutputStream("idea_test\\java.txt");
//void write(int b):將指定的位元組寫入此檔案輸出流
fo.write(97);
//釋放資源:關閉此檔案的輸出流并釋放與此流關聯的任何系統資源
fo.close();
}
}
運行結果:

位元組流寫資料的三種方式

//寫入abcde 第一種
fo.write(97);
fo.write(98);
fo.write(99);
fo.write(100);
fo.write(101);
//寫入abcde 第二種
byte[] b = {97,98,99,100,101};
//或者,回傳字串中的位元組陣列
//byte[] b = "abcde".getBytes();
fo.write(b);
//寫入abcde 第三種
byte[] b = {97,98,99,100,101};
//引數:位元組陣列 索引起始位置 索引結束位置
fo.write(b,0,b.length);
位元組流寫資料的兩個小問題
- 位元組流寫資料如何實作換行?
- Windows: \r\n
- Linux: \n (win11用這個也可以)
- Mac: \r
- 位元組流寫資料如何實作追加寫入?
- public FileOutputStream?(File file, boolean append)
//追加寫入
public class IoDemo {
public static void main(String[] args) throws IOException {
//如果第二個引數為true,將在檔案末尾追加內容
//如果第二個引數不為true(不寫或者false),將不是追加,而是從檔案開頭開始覆寫內容
FileOutputStream fo = new FileOutputStream("idea_test\\java.txt",true);
//FileOutputStream fo = new FileOutputStream("idea_test\\java.txt",false);
//寫入十次”hello“
for (int i = 0; i < 10; i++) {
// 寫入位元組流
// getBytes()回傳字串中的位元組陣列
fo.write("hello".getBytes());
fo.write("\n".getBytes());
}
fo.close();
}
}
位元組流寫資料加例外處理
public class IoDemo {
public static void main(String[] args) {
//初始化為null
FileOutputStream fo = null;
try {
//可能出現例外的代碼
fo = new FileOutputStream("idea_test\\java.txt");
fo.write("世界杯".getBytes());
} catch (IOException e) {
//例外處理的代碼
e.printStackTrace();
} finally {//被finally控制的陳述句,一定會執行,除非JVM退出
//null調方法會報空指標例外,所以fo不為null才能執行close()釋放資源操作
if (fo != null) {
try {
//close()有編譯時例外,用try...catch()處理一下
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
位元組流讀資料(一次讀一個位元組)
FileInputStream:從檔案系統中的檔案獲取輸入位元組
- FileInputStream(String name):通過打開與實際檔案的連接來創建一個FileInputStream,該檔案由檔案系統中的路徑名name命名,
使用位元組輸入流讀資料的步驟:
- 創建位元組輸入流物件
- 呼叫位元組輸入流物件的讀資料方法
- 釋放資源
一次讀取一個位元組 read(),如果回傳-1說明到了檔案末尾
public class IoDemo {
public static void main(String[] args) {
//需求:把檔案java.txt中的內容讀取出來在控制臺輸出
File file = new File("idea_test\\java.txt");
//初始化fi
FileInputStream fi = null;
try {
//創建位元組輸出流物件
fi = new FileInputStream(file);
//呼叫位元組輸入流物件的讀資料方法,一次讀取一個位元組
int read;
while ((read = fi.read()) != -1) {
//輸出
System.out.print((char) read);
}
//釋放資源
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fi != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
再補充一個一次性讀取檔案全部內容的:
public class IoDemo {//throws拋出例外
public static void main(String[] args) throws IOException {
//需求:把檔案java.txt中的內容讀取出來在控制臺輸出
File file = new File("idea_test\\java.txt");
//創建檔案輸入流物件
FileInputStream fi = new FileInputStream(file);
//file.length()回傳值是long,但byte只能裝整形大小的空間,所以要強轉
byte[] buffer = new byte[(int) file.length()];
//呼叫位元組輸入流物件的讀資料方法,讀取檔案全部內容
fi.read(buffer);
System.out.print(new String(buffer));
//釋放資源
fi.close();
}
}
注意:檔案位元組流讀取檔案,一次讀一個位元組,遇到中文會亂碼;一次讀取檔案的所有內容,中文不會亂碼,
位元組流復制文本檔案
思路:
- 根據資料源創建位元組輸入流物件
- 根據目的地創建位元組輸出流物件
- 讀寫資料,復制文本檔案
- 釋放資源
public class IoDemo {
public static void main(String[] args) throws IOException {
//需求:把檔案G:\FileTest\Hello.txt中的內容復制到模塊目錄下的java.txt
//1.根據資料源創建輸入流物件
InputStream fo = new FileInputStream("G:\\FileTest\\Hello.txt");
//2.根據目的地創建輸出流物件
OutputStream fi = new FileOutputStream("idea_test\\java.txt");
//一次讀取一個位元組,一次寫入一個位元組
//3.讀檔案
int read;
while ((read = fo.read()) != -1) {
//4.寫入檔案
fi.write(read);
}
//5.釋放資源,先關閉輸出流,在關閉輸入流
fo.close();
fi.close();
}
}
位元組流讀資料(一次讀一個位元組陣列)
使用位元組輸入流讀資料的步驟
- 創建位元組輸入流物件
- 呼叫位元組輸入流物件的讀資料方法
- 釋放資源
public class IoDemo1 {
public static void main(String[] args) throws IOException {
//創建位元組輸入流物件
InputStream fo = new FileInputStream("idea_test\\java.txt");
//創建一個位元組陣列,長度一般為1024及其整數倍
byte[] bytes = new byte[1024];
//創建位元組輸入流物件的讀資料方法,
// len 一次讀取的位元組陣列的長度
int len;
while ((len = fo.read(bytes)) != -1) {
System.out.print(new String(bytes, 0, len));
}
//釋放資源
fo.close();
}
}
注意:讀含有中文的檔案時,建議一次讀完,
因為一個漢字占2~3個位元組,如果正好讀了半個漢字,那就亂碼了(如圖),
后面的內容用字符流就更方便了,因為一個漢字一個字母都是一個字符,
位元組流復制圖片
思路
- 根據資料源創建位元組輸入流物件
- 根據目的地創建位元組輸出流物件
- 讀寫資料,復制圖片
- 釋放資源
public class IoDemo2 {
public static void main(String[] args) throws IOException {
//需求:把圖片G:\FileTest\dog.jpg復制到模塊目錄下的dog.jpg
//1.根據資料源創建輸入流物件
InputStream fo = new FileInputStream("G:\\FileTest\\dog.jpg");
//2.根據目的地創建輸出流物件
OutputStream fi = new FileOutputStream("idea_test\\dog.jpg");
//定義一個位元組陣列
byte[] bytes = new byte[1024];
//一次讀取一個位元組陣列,一次寫入一個位元組陣列
int len;
//3.回圈讀寫圖片
while ((len = fo.read(bytes)) != -1) {
//4.寫入檔案
fi.write(bytes,0,len);
}
//5.釋放資源,先關閉輸出流,在關閉輸入流
fo.close();
fi.close();
}
}
運行結果:

IO字符流
位元組緩沖流

位元組緩沖輸出流寫資料
public class Demo {
public static void main(String[] args) throws IOException {
//位元組緩沖輸出流寫資料
//創建位元組緩沖輸出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("idea_test\\java.txt"));
//寫入資料
bos.write("hello\r\n".getBytes());
bos.write("java\r\n".getBytes());
//釋放資源
bos.close();
}
}
位元組緩沖輸入流讀資料
public class Demo {
public static void main(String[] args) throws IOException {
//位元組緩沖輸入流讀資料
//創建位元組緩沖輸入流,一次性從檔案中讀取8192個位元組
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("idea_test\\java.txt"));
//一次讀取的位元組流陣列長度
//每次讀取的1024個位元組,是直接從位元組緩沖流那8192個位元組里拿的,拿完之后位元組緩沖流會再次從檔案中一次性讀取8192個位元組
byte[] bytes = new byte[1024];
//讀資料
int len;
while ((len = bis.read(bytes)) != -1) {
System.out.print(new String(bytes,0,len));
}
//釋放資源
bis.close();
}
}
位元組流復制視頻
思路
- 根據資料源創建位元組輸入流物件
- 根據目的地創建位元組輸出流物件
- 讀寫資料,復制視頻
- 釋放資源
位元組緩沖流一次讀寫一個位元組陣列
public class Demo1 {
public static void main(String[] args) throws IOException {
//把G:\FileTest\video.avi復制到模塊目錄下idea_test\video.avi
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("G:\\FileTest\\video.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("idea_test\\video.avi"));
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
//System.out.println(new String(bytes,0,len));
}
bos.close();
bis.close();
}
}
速度:
- 基本位元組流一次讀寫一個位元組 < 基本位元組流一次讀寫一個位元組陣列 < 位元組緩沖流一次讀寫一個位元組 < 位元組緩沖流一次讀寫一個位元組陣列
為什么出現字符流
- 位元組流操作中文不方便,所以Java提供了字符流
- 字符流 = 位元組流 + 編碼表
- 用位元組流每次讀寫一個位元組復制文本時,底層操作會自動進行位元組拼接中文
- 漢字在存盤的時候,無論選擇哪種編碼格式,第一個位元組都是負數
案例:
public class Demo1 {
public static void main(String[] args) throws IOException {
String s = "abc";
byte[] bytes = s.getBytes("UTF-8");
byte[] bytes1 = s.getBytes("GBK");
//[97, 98, 99]
System.out.println(Arrays.toString(bytes));
//[97, 98, 99]
System.out.println(Arrays.toString(bytes1));
String s1 = "肥胖";
byte[] bytes2 = s1.getBytes("UTF-8");
byte[] bytes3 = s1.getBytes("GBK");
//[-24, -126, -91, -24, -125, -106]
System.out.println(Arrays.toString(bytes2));
//[-73, -54, -59, -42]
System.out.println(Arrays.toString(bytes3));
}
}
編碼表
- 計算機存盤資料是二進制的(0和1)
- 編碼和解碼
- 按照規則,將字符存盤到計算機中,稱為編碼;反之,將存盤到計算機中的二進制內容按照規則決議顯示出來,稱為解碼
- 編碼和解碼的規則必須一致,否則會出現亂碼
- 字符編碼
- 就是一套自然語言的字符與二進制數之間的對應關系,如(A,65)
字符集
- 是一個系統支持的所有字符集的集合,包括各國家文字,標點符號,圖形符號,數字等
- 計算機要存盤和識別各種字符集符號,就要進行字符編碼,一套字符集必然至少有一套字符編碼規則,常見的字符集有ASCII字符集,GBXXX字符集,Unicode字符集等



字串中的編碼解碼問題
public class Demo1 {
public static void main(String[] args) throws IOException {
String s = "接化發";
//默認規則編碼
byte[] bys = s.getBytes();
System.out.println(Arrays.toString(bys));
//指定規則編碼
byte[] bys1 = s.getBytes("GBK");
System.out.println(Arrays.toString(bys1));
//默認規則解碼
String s1 = new String(bys);
System.out.println(s1);
//指定規則解碼
String s2 = new String(bys1, "GBK");
System.out.println(s2);
}
}
運行結果:
[-26, -114, -91, -27, -116, -106, -27, -113, -111]
[-67, -45, -69, -81, -73, -94]
接化發
接化發
字符流中的編碼解碼問題
字符流抽象基類
- Reader:字符輸入流的抽象類
- Writer:字符輸出流的抽象類
InputStreamReader:是從位元組流到字符流的橋梁
OutputStreamWriter:是從字符流到位元組流的橋梁
public class Demo1 {
public static void main(String[] args) throws IOException {
//字符輸出流物件 默認編碼格式
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("idea_test\\java.txt"));
//字符輸出流物件 指定編碼格式
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("idea_test\\java.txt"),"UTF-8");
osw.write("蔬菜");
osw.close();
//字符輸入流物件 指定編碼格式
InputStreamReader isr = new InputStreamReader(new FileInputStream("idea_test\\java.txt"),"UTF-8");
//一次讀取一個字符
int ch;
while ((ch = isr.read()) != -1) {
System.out.print((char)ch);
}
isr.close();
}
}
字符流寫資料的5種方式

flush()和close()的區別
- flush()重繪流,重繪之后還可以寫資料
- close()關閉流,關閉流之前會自動執行重繪流操作,關閉之后就不能再繼續寫資料了
public class Demo2 {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("idea_test\\java.txt"));
osw.write(97);
/**
* 重繪緩沖
* 字符流寫資料如果不重繪流,那么資料就在緩沖區中,沒close()之前,打開檔案java.txt看不到資料
* 字符流相對于位元組流是有緩沖的,真正寫資料是位元組流
*/
osw.flush();
//close():關閉流之前會自動執行重繪流操作
//flush()重繪流之后還可以繼續寫資料,但是close()關閉流之后就不能繼續寫資料了
osw.close();
}
}
字符流寫資料的5種方式:
public class Demo2 {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("idea_test\\java.txt"));
//1.寫入一個字符:a
osw.write(97);
//2.寫入一個字符陣列:abcde
char[] chs = {'a', 'b', 'c', 'd', 'e'};
osw.write(chs);
//3.寫入一個字符陣列的一部分:abc
osw.write(chs, 0, 3);
//4.寫入一個字串:世界杯
String s = "世界杯";
osw.write(s);
//5.寫入一個字串的一部分:界
osw.write(s,1,1);
osw.flush();
osw.close();
}
}
字符流讀資料的2種方式

public class Demo2 {
public static void main(String[] args) throws IOException {
//創建字符輸入流物件
InputStreamReader isr = new InputStreamReader(new FileInputStream("idea_test\\java.txt"));
//1.一次讀一個字符
int ch;
while ((ch = isr.read()) != -1) {
System.out.print((char) ch);
}
//2.一次讀取一個字符陣列
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs)) != -1) {
System.out.print(new String(chs,0,len));
}
isr.close();
}
}
字符流復制Java檔案
思路:
- 根據資料源創建字符輸入流物件
- 根據目的地創建字符輸出流物件
- 讀寫資料,復制檔案
- 釋放資源
public class Demo2 {
public static void main(String[] args) throws IOException {
//需求:將模塊下的idea_test\java.txt,復制到idea_test\java1.txt
//創建字符輸入流物件
InputStreamReader isr = new InputStreamReader(new FileInputStream("idea_test\\java.txt"));
//創建字符輸出流物件
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("idea_test\\java1.txt"));
//讀寫資料,復制檔案
char[] chs = new char[1024];
int len;
while ((len = isr.read(chs)) != -1) {
osw.write(chs,0,len);
}
osw.close();
isr.close();
}
}
字符流復制Java檔案(改進版)

思路:
- 根據資料源創建字符輸入流物件
- 根據目的地創建字符輸出流物件
- 讀寫資料,復制檔案
- 釋放資源
public class Demo2 {
public static void main(String[] args) throws IOException {
//需求:將模塊下的idea_test\java.txt,復制到idea_test\java1.txt
//創建字符輸入流物件
FileReader fr = new FileReader("idea_test\\java.txt");
//創建字符輸出流物件
FileWriter fw = new FileWriter("idea_test\\java2.txt");
//讀寫資料,復制檔案
char[] chs = new char[1024];
int len;
while ((len = fr.read(chs)) != -1) {
fw.write(chs,0,len);
}
fw.close();
fr.close();
}
}
字符緩沖流

構造方法
- BufferedWriter(Writer out)
- BufferedReader(Reader in)
public class Demo2 {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java.txt"));
bw.write("hello\n");
bw.write("world\r");
bw.write("java\r\n");
bw.write(97);
bw.write(98);
bw.write(99);
bw.close();
//緩沖流默認一次從檔案里讀取8192個字符
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java1.txt"));
//每次讀取的1024個字符,是直接從緩沖流那8192個字符里拿的,拿完之后緩沖流會再次從檔案中一次性讀取8192個字符
char[] chs = new char[1024];
int len;
while ((len = br.read(chs)) != -1){
System.out.println(new String(chs, 0, len));
}
br.close();
}
}
換行
- /r Mac
- /n Unix/Linux
- /r/n Windows
- 不過我在windows11上測驗換行,以上三種都可以,
字符緩沖流復制Java檔案
思路:
- 根據資料源創建字符緩沖輸入流物件
- 根據目的地創建字符緩沖輸出流物件
- 讀寫資料,復制檔案
- 釋放資源
public class Demo2 {
public static void main(String[] args) throws IOException {
//需求:java字符緩沖流復制檔案,從idea_test\java.txt復制到idea_test\java3.txt
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java3.txt"));
char[] chs = new char[1024];
int len;
while ((len = br.read(chs)) != -1){
bw.write(chs,0,len);
}
bw.close();
br.close();
}
}
字符緩沖流特有功能

newLine():就是根據系統,自動識別的換行符
readLine():一次讀一行資料,如果讀到了結尾則回傳null;只讀每行的內容,不讀行尾終止符
public class Demo2 {
public static void main(String[] args) throws IOException {
//寫資料
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java.txt"));
for (int i = 0; i < 10; i++) {
bw.write("hello-"+i);
//換行
bw.newLine();
bw.flush();
}
bw.close();
//讀資料
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
String s;
while ((s = br.readLine()) != null){
System.out.println(s);
}
br.close();
}
}
字符緩沖流特有功能復制Java檔案
思路:
- 根據資料源創建字符緩沖輸入流物件
- 根據目的地創建字符緩沖輸出流物件
- 讀寫資料,復制檔案(使用字符緩沖流特有功能)
- 釋放資源
public class Demo2 {
public static void main(String[] args) throws IOException {
//需求:java字符緩沖流(特有功能)復制檔案,從idea_test\java.txt復制到idea_test\java3.txt
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java4.txt"));
char[] chs = new char[1024];
String s;
while ((s = br.readLine())!=null){
//每寫一行資料,換行,重繪
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
IO流小結
1.位元組流


位元組流小結
- 位元組流可以復制【任意檔案】資料,有四種方式,一般采用位元組緩沖流一次讀寫一個位元組陣列的方式
2.字符流


字符流小結
- 字符流只能復制【文本資料】,有五種方式,一般采用字符緩沖流的特有功能
IO練習
1.集合到檔案
public class Demo {
public static void main(String[] args) throws IOException {
//需求:將ArrayList集合中的字串資料寫入到文本檔案,要求每一個字串元素作為檔案中的一行資料
//1.創建ArrayList集合
ArrayList<String> list = new ArrayList<>();
//2.向集合中創建字串元素
list.add("hello");
list.add("world");
list.add("java");
list.add("世界杯");
//3.創建字符緩沖流輸入物件
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java.txt"));
//4.遍歷集合,得到每一個字串資料
for (String s : list) {
//5.呼叫字符緩沖流物件的方法寫資料
bw.write(s);
bw.newLine();
bw.flush();
}
//6.釋放資源
bw.close();
}
}
運行結果:

2.檔案到集合
public class Demo1 {
public static void main(String[] args) throws IOException {
//需求:把文本檔案中的資料讀取到集合中,并遍歷集合,要求:文本中每一行資料是一個集合元素
//1.創建字符緩沖輸入流物件
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
//2.創建ArrayList集合
ArrayList<String> list = new ArrayList<>();
//3.呼叫字符緩沖輸入流物件的方法讀資料
String s;
while ((s = br.readLine()) != null) {
//4.把讀到的字串資料存盤到集合
list.add(s);
}
//5.釋放資源
br.close();
//6.遍歷集合
for (String s1 : list) {
System.out.println(s1);
}
}
}
運行結果:
hello
world
java
世界杯
3.點名器
public class Demo2 {
public static void main(String[] args) throws IOException {
//需求:檔案中存盤了班級同學的姓名,每一個姓名占一行,要求通程序式實作隨機點名
//1.創建字符緩沖輸入流物件
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
//2.創建ArrayList集合
ArrayList<String> list = new ArrayList<>();
//3.呼叫字符緩沖輸入流物件的方法讀資料
String line;
while ((line = br.readLine()) != null) {
//4.把讀到的字串資料存盤到集合
list.add(line);
}
//5.釋放資源
br.close();
//6.使用Random產生一個亂數,亂數的范圍在:[0,集合長度)
Random random = new Random();
int i = random.nextInt(list.size());
//7.把產生的亂數作為索引,在集合中獲取值
String s = list.get(i);
//8.將獲取到的值輸出到控制臺
System.out.println(s);
}
}
4.集合到檔案(改進版)
public class Demo1 {
public static void main(String[] args) throws IOException {
//需求:將ArrayList集合中的學生資料寫入到文本檔案,要求每一個向何生物件的資料作為檔案中的一行資料
//格式:學號,姓名,年齡,居住地
//1.定義學生類
//2.創建ArrayList集合
ArrayList<Student> list = new ArrayList<>();
//3.創建學生物件
Student s1 = new Student("初二001", "小明", 15, "西安");
Student s2 = new Student("初二002", "小紅", 16, "北京");
Student s3 = new Student("初二003", "小軍", 17, "上海");
Student s4 = new Student("初二004", "白展堂", 14, "云南");
Student s5 = new Student("初二005", "史珍香", 13, "廣州");
//4.把學生物件添加到集合中
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
//5.創建字符緩沖輸出流物件
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java.txt"));
//6.遍歷集合,得到每一個學生物件
for (Student stu : list) {
//7.把學生物件的資料拼接成指定格式的字串
StringBuffer sb = new StringBuffer();
sb.append(stu.getId() + "," + stu.getName() + "," + stu.getAge() + "," + stu.getAddress());
//8.呼叫字符緩沖輸出流物件的方法寫資料
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
//9.釋放資源
bw.close();
}
}
5.檔案到集合(改進版)
public class Demo3 {
public static void main(String[] args) throws IOException {
/**
* 需求:把文本檔案中的資料讀取到集合中,并遍歷集合,
* 要求:文本中每一行資料是一個學生物件的成員變數值
* 格式:學號,姓名,年齡,居住地
*/
//1.定義學生類
//2.創建字符緩沖輸入流物件
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
//3.創建ArrayList集合
ArrayList<Student> list = new ArrayList<>();
String line;
//4.呼叫字符緩沖輸入流物件的方法讀資料
while ((line = br.readLine()) != null) {
//5.把讀取到的字串用split分割,得到一個字串陣列
String[] s = line.split(",");
//6.創建學生物件
Student stu = new Student();
//7.把字串陣列中的每一個元素取出來,賦值給學生物件的成員變數
stu.setId(s[0]);
stu.setName(s[1]);
stu.setAge(Integer.parseInt(s[2]));
stu.setAddress(s[3]);
//8.把學生物件添加到集合
list.add(stu);
}
//9.釋放資源
br.close();
//10.遍歷集合
for (Student s : list) {
//直接輸出,因為Student類中重寫了toString()
System.out.println(s);
}
}
}
運行結果:
Student{id='初二001', name='小明', age=15, address='西安'}
Student{id='初二002', name='小紅', age=16, address='北京'}
Student{id='初二003', name='小軍', age=17, address='上海'}
Student{id='初二004', name='白展堂', age=14, address='云南'}
Student{id='初二005', name='史珍香', age=13, address='廣州'}
標準流和列印流
集合到檔案資料排序(改進版)
定義學生類:
public class Student {
private String name;
private int yuwen;
private int shuxue;
private int yingyu;
public Student() {
}
public Student(String name, int yuwen, int shuxue, int yingyu) {
this.name = name;
this.yuwen = yuwen;
this.shuxue = shuxue;
this.yingyu = yingyu;
}
//定義獲取總分的方法
public int getSum() {
return this.yuwen + this.shuxue + this.yingyu;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getYuwen() {
return yuwen;
}
public void setYuwen(int yuwen) {
this.yuwen = yuwen;
}
public int getShuxue() {
return shuxue;
}
public void setShuxue(int shuxue) {
this.shuxue = shuxue;
}
public int getYingyu() {
return yingyu;
}
public void setYingyu(int yingyu) {
this.yingyu = yingyu;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", yuwen=" + yuwen +
", shuxue=" + shuxue +
", yingyu=" + yingyu +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (yuwen != student.yuwen) return false;
if (shuxue != student.shuxue) return false;
if (yingyu != student.yingyu) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + yuwen;
result = 31 * result + shuxue;
result = 31 * result + yingyu;
return result;
}
}
測驗類:
public class Demo {
public static void main(String[] args) throws IOException {
/**
* 需求:鍵盤錄入幾個學生資訊(姓名,語文成績,數學成績,英語成績)
* 要求:按照成績總分由高到低寫入檔案(排序規則)
*/
Set<Student> list = new TreeSet<>(new Comparator<Student>() {
//匿名內部類重寫排序方法
@Override
public int compare(Student o1, Student o2) {
//總分從低到高
int num = o2.getSum() - o1.getSum();
//如果總分相同,按照語文成績從高到低
int num1 = num == 0 ? o1.getYuwen() - o2.getYuwen() : num;
//如果總分相同,語文成績也相同,按照數學成績從高到低
int num2 = num1 == 0 ? o1.getShuxue() - o2.getShuxue() : num1;
//如果總分相同,語文成績也相同,數學成績也相同,說明英語成績肯定相同,那就按照姓名的字母排序
int num3 = num2 == 0 ? o1.getName().compareTo(o2.getName()) : num2;
return num3;
}
});
for (int i = 0; i < 5; i++) {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入第" + (i + 1) + "學生資訊:");
System.out.println("姓名:");
String name = sc.nextLine();
System.out.println("請輸入語文成績:");
int yuwen = sc.nextInt();
System.out.println("請輸入數學成績:");
int shuxue = sc.nextInt();
System.out.println("請輸入英語成績:");
int yingyu = sc.nextInt();
Student s = new Student(name, yuwen, shuxue, yingyu);
list.add(s);
}
BufferedWriter bw = new BufferedWriter(new FileWriter("idea_test\\java.txt"));
for (Student stu : list) {
StringBuilder sb = new StringBuilder();
sb.append(stu.getName() + "," + stu.getYuwen() + "," + stu.getShuxue() + "," + stu.getYingyu() + ",總分:" + stu.getSum());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
bw.close();
}
}
運行結果:總分從高到低排序
關羽,89,94,1,總分:184
孫權,1,99,3,總分:103
張飛,1,88,9,總分:98
caocao,1,55,9,總分:65
劉備,1,2,3,總分:6
復制單級檔案夾
單級檔案夾:檔案夾中只有檔案,沒有檔案夾
資料源目錄

public class Demo2 {
public static void main(String[] args) throws IOException {
/**
* 需求復制單級檔案夾及其內容
*/
//1.創建資料源目錄
File file = new File("G:\\FileTest\\dog");
//2.獲取創建資料源目錄的名稱
String name = file.getName();
//3.創建目的地File物件
File file1 = new File("idea_test", name);
//4.判斷目的地是否已經存在該名稱的檔案夾
if (!file1.exists()) {
//5.在目的地創建該名稱的檔案夾
file1.mkdir();
}
//6.獲取資料源檔案夾下的所有檔案
File[] files = file.listFiles();
//7.遍歷陣列,得到每一個檔案物件
for (File fi : files) {
//8.獲取檔案名稱
String fiName = fi.getName();
//9.在目的地檔案夾中,創建fiName同名稱的檔案
File fil = new File(file1, fiName);
//10.復制檔案內容:將資料源檔案內容復制到目的地檔案中
copyFile(fi, fil);
}
}
/**
* 位元組緩沖流復制檔案內容
* @param f1 資料源檔案
* @param f2 目的地檔案
*/
public static void copyFile(File f1, File f2) throws IOException {
//緩沖位元組輸入流物件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
//緩沖位元組輸出流物件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2));
//讀寫檔案
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
bos.close();
bis.close();
}
}
運行結果:

復制多級檔案夾
多級檔案夾:檔案夾下還有檔案夾
資料源檔案夾:

public class Demo3 {
public static void main(String[] args) throws IOException {
//1.創建資料源目錄
File srcFile = new File("G:\\FileTest");
//2.創建目的地File物件
File destFile = new File("D:\\");
//復制檔案夾,引數為資料源File物件 和 目的地File物件
copyFolder(srcFile,destFile);
}
/**
* 復制檔案夾
* @param srcFile 資料源檔案夾操作物件
* @param destFile 目的地檔案夾操作物件
*/
private static void copyFolder(File srcFile,File destFile) throws IOException {
//判斷資料源是否是目錄,如果是目錄
if (srcFile.isDirectory()){
//獲取資料源檔案夾名稱
String srcFileName = srcFile.getName();
//目的地檔案夾名稱
File destFileName = new File(destFile, srcFileName);
//判斷新檔案夾名稱在目的地是否存在
if(!destFileName.exists()){
destFileName.mkdir();
}
//獲取資料源檔案夾下的檔案
File[] files = srcFile.listFiles();
//遍歷該陣列,得到每一個元素物件
for (File file : files) {
//file可能是檔案,也可能是檔案夾;所以遞回呼叫復制檔案夾方法
copyFolder(file,destFileName);
}
}else {//如果資料源不是目錄
File newFile = new File(destFile, srcFile.getName());
copyFile(srcFile,newFile);
}
}
/**
* 復制檔案內容
* @param f1 資料源檔案操作物件
* @param f2 目的地檔案操作物件
*/
public static void copyFile(File f1, File f2) throws IOException {
//緩沖位元組輸入流物件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
//緩沖位元組輸出流物件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2));
//讀寫檔案
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
bos.close();
bis.close();
}
}
目的地檔案夾:

復制檔案的例外處理
案例:復制檔案;以下是幾種處理例外的方法
- 拋出處理

- try...catch...finally...處理

/**
* 復制檔案內容
*
* @param f1 資料源檔案操作物件
* @param f2 目的地檔案操作物件
*/
public static void copyFile(File f1, File f2) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//緩沖位元組輸入流物件
bis = new BufferedInputStream(new FileInputStream(f1));
//緩沖位元組輸出流物件
bos = new BufferedOutputStream(new FileOutputStream(f2));
//讀寫檔案
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- JDK7的改進方案

/**
* 位元組緩沖流復制檔案內容
* @param f1 資料源檔案
* @param f2 目的地檔案
* JDK7之后的寫法,會自動釋放資源,不需要close()
*/
public static void copyFile1(File f1, File f2) {
//注意try后面的的小括號
try(//緩沖位元組輸入流物件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
//緩沖位元組輸出流物件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2))) {
//讀寫檔案
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
- JDK9的改進方案

/**
* 位元組緩沖流復制檔案內容
* @param f1 資料源檔案
* @param f2 目的地檔案
*/
public static void copyFile2(File f1, File f2) throws FileNotFoundException {
//緩沖位元組輸入流物件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
//緩沖位元組輸出流物件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2));
try(bis;bos) {
//讀寫檔案
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
標準輸入流
System類中有兩個靜態成員變數
- public static final InputStream in:“標準”輸入流,此流已經 打開并準備提供輸入資料,通常此流 對應于鍵盤輸入或由 指定的其他輸入源 主機環境或用戶,
- public static final PrintStream out:“標準”輸出流,此流已經 打開并準備接受輸出資料,通常此流 對應于顯示輸出或其他輸出目標 由主機環境或用戶指定,
- 自己實作輸入操作
public class Demo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入一個字串:");
String line = br.readLine();
System.out.println("你輸入的字串是:" + line);
System.out.println("請輸入一個整數:");
System.out.println("你輸入的整數是:"+Integer.parseInt(br.readLine()));
}
}
運行:
請輸入一個字串:
hello
你輸入的字串是:hello
請輸入一個整數:
123
你輸入的整數是:123
- Java提供的輸入類Scanner
//自己實作輸入操作太麻煩,所以Java提供了一個類
Scanner sc = new Scanner(System.in);
標準輸出流
public class Demo1 {
public static void main(String[] args) {
PrintStream out = System.out;
out.print("hello");
out.println("world");
out.println(100);
/**
* System.out的本質是一個位元組輸出流
* print()必須有引數
* println()可以沒有引數
* PrintStream類有的方法,System.out都可以呼叫
*/
System.out.println();
System.out.print("世界杯");
System.out.println(123);
}
}
運行:
helloworld
100
世界杯123
位元組列印流
列印流分類:
- 位元組列印流:PrintStream
- 字符列印流:PrintWriter
列印流的特點:
- 只負責輸出資料,不負責讀取資料
- 有自己的特有方法
位元組列印流
- PrintStream(String fileName):使用指定的檔案名創建新的列印流
- 使用繼承父類的方法寫資料,查看的時候會轉碼;使用自己的特有方法寫資料,查看的資料原樣輸出
public class Demo {
public static void main(String[] args) throws FileNotFoundException {
//創建位元組列印流物件
PrintStream ps = new PrintStream("idea_test\\java1.txt");
//寫資料
// 1.位元組輸出流寫資料
//使用繼承父類的方法寫資料,查看的時候會轉碼
ps.write(97);
ps.write(98);
ps.println();
// 2.位元組列印流特有方法寫資料
//使用自己的特有方法寫資料,查看的資料原樣輸出
ps.println(97);
ps.print(98);
ps.close();
}
}
運行結果:

字符列印流

public class Demo1 {
public static void main(String[] args) throws IOException {
//創建字符列印流物件
PrintWriter pw = new PrintWriter("idea_test\\java2.txt");
pw.write("世界杯");
pw.write("\r\n");
pw.flush();
pw.write("足球");
pw.write("\r\n");
pw.flush();
pw.println("hello");
pw.flush();
pw.println("world");
pw.flush();
pw.close();
//PrintWriter(Writer out,boolean outFlush)
//創建一個新的PrintWriter,true自動重繪flush
PrintWriter pw1 = new PrintWriter(new FileWriter("idea_test\\java3.txt"), true);
pw1.println("麻辣");
pw1.println("米線");
pw1.close();
}
}
運行結果:


復制Java檔案(列印流改進版)
思路
- 根據資料源創建字符輸入流物件
- 根據目的地創建字符輸出流物件
- 讀寫資料,復制檔案
- 釋放資源
public class Demo2 {
public static void main(String[] args) throws IOException {
/*需求:把idea_test\java.txt復制到idea_test\java4.txt*/
BufferedReader br = new BufferedReader(new FileReader("idea_test\\java.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("idea_test\\java4.txt"), true);
//讀寫資料
String line;
while((line = br.readLine())!=null){
pw.println(line);
}
pw.close();
br.close();
}
}
物件序列化流
物件序列化流
物件序列化流
- 就是將物件保存到磁盤中,或者在網路中傳輸物件
- 這種機制就是使用一個位元組序串列示一個物件,該位元組序列包含:物件的型別,物件的資料和物件中存盤的屬性等
- 位元組序列寫到檔案之后,相當于檔案中持久保存了一個物件的資訊
- 反之,該位元組序列還可以從檔案中讀取回來,重構物件,對它進行反序列化
物件序列化流:ObjectOutputStream
物件反序列化流:ObjectInputStream

public class Demo {
public static void main(String[] args) throws IOException {
/*需求:將學生物件序列化到檔案idea_test\hello.txt*/
//創建物件序列化流操作物件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("idea_test\\hello.txt"));
//創建學生物件;Student類實作了Serializable介面
Student s = new Student("馬超", 30);
//序列化物件
oos.writeObject(s);
//釋放資源
oos.close();
}
}
物件反序列化流

public class Demo1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/*需求:將檔案idea_test\hello.txt中的學生物件反序列化*/
//創建物件反序列化流操作物件
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("idea_test\\hello.txt"));
//反序列化物件
Object o = ois.readObject();
//強轉物件型別
System.out.println((Student)o);
//釋放資源
ois.close();
}
}
運行結果:
//Student類中重寫了toString()
Student{name='馬超', age=30}
補充問題

Properties類
Properties概述
- 是一個Map體系的集合類
- Properties可以保存到流中或從流中加載
- Properties不能有泛型;默認是<Object,Object>型別
Properties作為Map集合
public class PropertiesDemo {
public static void main(String[] args) {
//創建集合物件
Properties p = new Properties();
//添加元素
p.put("高一1班", "張鐵牛");
p.put("高一2班", "馬牛旦");
p.put("高一3班", "李桂皮");
//遍歷
for (Object key : p.keySet()) {
Object value = https://www.cnblogs.com/chawaner/archive/2022/12/02/p.get(key);
System.out.println(key +"," + value);
}
}
}
運行結果:
高一3班,李桂皮
高一2班,馬牛旦
高一1班,張鐵牛
Properties作為集合的特有方法

public class PropertiesDemo {
public static void main(String[] args) {
//創建集合物件
Properties p = new Properties();
System.out.println("Properties集合:" + p);
//添加元素
p.setProperty("高一1班", "張鐵牛");
p.setProperty("高一2班", "馬牛旦");
p.setProperty("高一3班", "李桂皮");
//回傳鍵的合集
Set<String> keys = p.stringPropertyNames();
//遍歷
for (String key : keys) {
//根據鍵獲取值
String value = https://www.cnblogs.com/chawaner/archive/2022/12/02/p.getProperty(key);
System.out.println(key +"," + value);
}
}
}
運行結果:
Properties集合:{}
高一3班,李桂皮
高一2班,馬牛旦
高一1班,張鐵牛
Properties和IO流相結合的方法

public class PropertiesDemo1 {
public static void main(String[] args) throws IOException {
//把集合中的資料保存到檔案
myStore();
//把檔案中的資料加載到集合
myLoad();
}
/**
* 把檔案中的資料加載到集合
*/
private static void myLoad() throws IOException {
//創建集合物件
Properties p = new Properties();
//創建字符輸入流物件
FileReader fr = new FileReader("idea_test\\fw.txt");
//讀取元素到集合
p.load(fr);
fr.close();
//輸出集合
System.out.println(p);
}
/**
* 把集合中的資料保存到檔案
*/
private static void myStore() throws IOException {
//創建集合物件
Properties p = new Properties();
//添加元素
p.setProperty("高一1班", "張鐵牛");
p.setProperty("高一2班", "馬牛旦");
p.setProperty("高一3班", "李桂皮");
//創建字符輸出流物件
FileWriter fw = new FileWriter("idea_test\\fw.txt");
//將元素寫入Properties
p.store(fw,null);
fw.close();
}
}
運行結果:

{高一3班=李桂皮, 高一2班=馬牛旦, 高一1班=張鐵牛}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538941.html
標籤:其他
上一篇:類的記憶體結構(一)



