Stream流,是jdk8開始新增的一套API(iava.util.stream),可以用于操作集合或者數組的數據。
優勢: Stream流大量的結合了Lambda的語法風格來編程,提供了一種更加強大,更加簡單的方式操作集合或者數組中的數據,代碼更簡潔,可讀性更好 (相對于采用原始集合api來操作數據)
Stream流的使用:首先得有一個數據源,再獲取到它的Stream流,通過調用Stream流中的各種方法對數據進行處理,然后進行統計,獲得最終結果。



public static void main(String[] args) {
// 1、如何獲取List集合的Stream流?
List<String> names = new ArrayList<>();
Collections.addAll(names, "張三豐","張無忌","周芷若","趙敏","張強");
Stream<String> stream = names.stream();
// 2、如何獲取Set集合的Stream流?
Set<String> set = new HashSet<>();
Collections.addAll(set, "劉德華","張曼玉","蜘蛛精","馬德","德瑪西亞");
Stream<String> stream1 = set.stream();
stream1.filter(s -> s.contains("德")).forEach(s -> System.out.println(s));
// 3、如何獲取Map集合的Stream流?
Map<String, Double> map = new HashMap<>();
map.put("古力娜扎", 172.3);
map.put("迪麗熱巴", 168.3);
map.put("馬爾扎哈", 166.3);
map.put("卡爾扎巴", 168.3);
Set<String> keys = map.keySet();
Stream<String> ks = keys.stream();
Collection<Double> values = map.values();
Stream<Double> vs = values.stream();
Set<Map.Entry<String, Double>> entries = map.entrySet();
Stream<Map.Entry<String, Double>> kvs = entries.stream();
kvs.filter(e -> e.getKey().contains("巴"))
.forEach(e -> System.out.println(e.getKey()+ "-->" + e.getValue()));
// 4、如何獲取數組的Stream流?
String[] names2 = {"張翠山", "東方不敗", "唐大山", "獨孤求敗"};
Stream<String> s1 = Arrays.stream(names2);
Stream<String> s2 = Stream.of(names2);
}
中間方法指的是調用完成后會返回新的Stream流,可以繼續使用(支持鏈式編程)。

public static void main(String[] args) {
List<Double> scores = new ArrayList<>();
Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.6, 25.0);
// 需求1:找出成績大于等于60分的數據,并升序后,再輸出。
scores.stream().filter(s -> s >= 60).sorted().forEach(s -> System.out.println(s));
List<Student> students = new ArrayList<>();
Student s1 = new Student("蜘蛛精", 26, 172.5);
Student s2 = new Student("蜘蛛精", 26, 172.5);
Student s3 = new Student("紫霞", 23, 167.6);
Student s4 = new Student("白晶晶", 25, 169.0);
Student s5 = new Student("牛魔王", 35, 183.3);
Student s6 = new Student("牛夫人", 34, 168.5);
Collections.addAll(students, s1, s2, s3, s4, s5, s6);
// 需求2:找出年齡大于等于23,且年齡小于等于30歲的學生,并按照年齡降序輸出.
students.stream().filter(s -> s.getAge() >= 23 && s.getAge() <= 30)
.sorted((o1, o2) -> o2.getAge() - o1.getAge())
.forEach(s -> System.out.println(s));
// 需求3:取出身高最高的前3名學生,并輸出。
students.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
.limit(3).forEach(System.out::println);
System.out.println("-----------------------------------------------");
// 需求4:取出身高倒數的2名學生,并輸出。 s1 s2 s3 s4 s5 s6
students.stream().sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
.skip(students.size() - 2).forEach(System.out::println);
// 需求5:找出身高超過168的學生叫什么名字,要求去除重復的名字,再輸出。
students.stream().filter(s -> s.getHeight() > 168).map(Student::getName)
.distinct().forEach(System.out::println);
// distinct去重復,自定義類型的對象(希望內容一樣就認為重復,重寫hashCode,equals)
students.stream().filter(s -> s.getHeight() > 168)
.distinct().forEach(System.out::println);
Stream<String> st1 = Stream.of("張三", "李四");
Stream<String> st2 = Stream.of("張三2", "李四2", "王五");
Stream<String> allSt = Stream.concat(st1, st2);
allSt.forEach(System.out::println);
}

收集stream流:就是把Stream流操作后的結果轉回到集合或者數組中去返回 (一個流只能收集一次)

public static void main(String[] args) {
List<Student> students = new ArrayList<>();
Student s1 = new Student("蜘蛛精", 26, 172.5);
Student s2 = new Student("蜘蛛精", 26, 172.5);
Student s3 = new Student("紫霞", 23, 167.6);
Student s4 = new Student("白晶晶", 25, 169.0);
Student s5 = new Student("牛魔王", 35, 183.3);
Student s6 = new Student("牛夫人", 34, 168.5);
Collections.addAll(students, s1, s2, s3, s4, s5, s6);
// 需求1:請計算出身高超過168的學生有幾人。
long size = students.stream().filter(s -> s.getHeight() > 168).count();
System.out.println(size);
// 需求2:請找出身高最高的學生對象,并輸出。
Student s = students.stream().max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
System.out.println(s);
// 需求3:請找出身高最矮的學生對象,并輸出。
Student ss = students.stream().min((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();
System.out.println(ss);
// 需求4:請找出身高超過170的學生對象,并放到一個新集合中去返回。
// 流只能收集一次。
List<Student> students1 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toList());
System.out.println(students1);
Set<Student> students2 = students.stream().filter(a -> a.getHeight() > 170).collect(Collectors.toSet());
System.out.println(students2);
// 需求5:請找出身高超過170的學生對象,并把學生對象的名字和身高,存入到一個Map集合返回。
Map<String, Double> map =
students.stream().filter(a -> a.getHeight() > 170)
.distinct().collect(Collectors.toMap(a -> a.getName(), a -> a.getHeight()));
System.out.println(map);
// Object[] arr = students.stream().filter(a -> a.getHeight() > 170).toArray();
Student[] arr = students.stream().filter(a -> a.getHeight() > 170).toArray(len -> new Student[len]);
System.out.println(Arrays.toString(arr));
}
File是java.io.包下的類,File類的對象,用于代表當前操作系統的文件 (可以是文件、或文件夾)。
通過File類提供的方法可以獲取文件本身的信息(大小,文件名,修改時間,文件類型)、判斷文件是否存在、創建文件、創建文件夾等。
注意:File對象只能對文件進行操作,不能操作文件中的內容。
創建File對象指代具體的文件。

public static void main(String[] args) {
// 1、創建一個File對象,指代某個具體的文件。
// 路徑分隔符
// File f1 = new File("D:/resource/ab.txt");
// File f1 = new File("D:\\resource\\ab.txt");
File f1 = new File("D:" + File.separator +"resource" + File.separator + "ab.txt");
System.out.println(f1.length()); // 文件大小
File f2 = new File("D:/resource");
System.out.println(f2.length()); //文件夾本身大小
// 注意:File對象可以指代一個不存在的文件路徑
File f3 = new File("D:/resource/aaaa.txt");
System.out.println(f3.length());
System.out.println(f3.exists()); // false
// 我現在要定位的文件是在模塊中,應該怎么定位呢?
// 絕對路徑:帶盤符的
// File f4 = new File("D:\\code\\javasepromax\\file-io-app\\src\\itheima.txt");
// 相對路徑(重點):不帶盤符,默認是直接去工程下尋找文件的。
File f4 = new File("file-io-app\\src\\itheima.txt");
System.out.println(f4.length());
}
注意:File對象可以指代一個不存在的文件路徑
File判斷和獲取方法:

創建和刪除方法:

public static void main(String[] args) throws Exception {
// 1、public boolean createNewFile():創建一個新文件(文件內容為空),創建成功返回true,反之。
File f1 = new File("D:/resource/itheima2.txt");
System.out.println(f1.createNewFile());
// 2、public boolean mkdir():用于創建文件夾,注意:只能創建一級文件夾
File f2 = new File("D:/resource/aaa");
System.out.println(f2.mkdir());
// 3、public boolean mkdirs():用于創建文件夾,注意:可以創建多級文件夾
File f3 = new File("D:/resource/bbb/ccc/ddd/eee/fff/ggg");
System.out.println(f3.mkdirs());
// 3、public boolean delete():刪除文件,或者空文件,注意:不能刪除非空文件夾。
System.out.println(f1.delete());
System.out.println(f2.delete());
File f4 = new File("D:/resource");
System.out.println(f4.delete());
}
注意: delete方法默認只能刪除文件和空文件夾,刪除后的文件不會進入回收站。
遍歷文件夾方法:

public static void main(String[] args) {
// 1、public String[] list():獲取當前目錄下所有的"一級文件名稱"到一個字符串數組中去返回。
File f1 = new File("D:\\course\\待研發內容");
String[] names = f1.list();
for (String name : names) {
System.out.println(name);
}
// 2、public File[] listFiles():(重點)獲取當前目錄下所有的"一級文件對象"到一個文件對象數組中去返回(重點)
File[] files = f1.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
File f = new File("D:/resource/aaa");
File[] files1 = f.listFiles();
System.out.println(Arrays.toString(files1));
}

文件搜索

public class RecursionTest3 {
public static void main(String[] args) throws Exception {
searchFile(new File("D:/") , "QQ.exe");
}
/**
* 去目錄下搜索某個文件
* @param dir 目錄
* @param fileName 要搜索的文件名稱
*/
public static void searchFile(File dir, String fileName) throws Exception {
// 1、把非法的情況都攔截住
if(dir == null || !dir.exists() || dir.isFile()){
return; // 代表無法搜索
}
// 2、dir不是null,存在,一定是目錄對象。
// 獲取當前目錄下的全部一級文件對象。
File[] files = dir.listFiles();
// 3、判斷當前目錄下是否存在一級文件對象,以及是否可以拿到一級文件對象。
if(files != null && files.length > 0){
// 4、遍歷全部一級文件對象。
for (File f : files) {
// 5、判斷文件是否是文件,還是文件夾
if(f.isFile()){
// 是文件,判斷這個文件名是否是我們要找的
if(f.getName().contains(fileName)){
System.out.println("找到了:" + f.getAbsolutePath());
Runtime runtime = Runtime.getRuntime();
runtime.exec(f.getAbsolutePath());
}
}else {
// 是文件夾,繼續重復這個過程(遞歸)
searchFile(f, fileName);
}
}
}
}
}
字符的編碼解碼
編碼

解碼

用于讀寫數據的(可以讀寫文件,或網絡中的數據…)

IO流整體體系

IO流總體來看主要的就有四大流:
字節輸入流
字節輸出流
字符輸入流
字符輸出流

具體而言:
字節流
字符流
緩沖流
轉換流
打印流
數據流
序列化流
注意:不同IO流體系的適用場景
字節流適合文件的復制
字符流適合文本內容的讀取
常用方法:

//第一步:創建FileInputStream文件字節輸入流管道,與源文件接通。
//第二步:調用read()方法開始讀取文件的字節數據。
//第三步:調用close()方法釋放資源
public static void main(String[] args) throws Exception {
// 1、創建文件字節輸入流管道,與源文件接通。
InputStream is = new FileInputStream(("test.txt"));
// 2、開始讀取文件的字節數據。
// public int read():每次讀取一個字節返回,如果沒有數據了,返回-1.
int b; // 用于記住讀取的字節。
while ((b = is.read()) != -1){
System.out.print((char) b);
}
// 3、同時讀多個字節
byte[] buffer = new byte[3];
int len; // 記住每次讀取了多少個字節。 abc 66
while ((len = is.read(buffer)) != -1){
// 注意:讀取多少,倒出多少。
String rs = new String(buffer, 0 , len);
System.out.print(rs);
}
//4、流使用完畢之后,必須關閉!釋放系統資源!
is.close();
}
注意:
1. 流使用完畢后必須調用close()方法釋放資源
2. 使用FilelnputStream每次讀取一個或多個字節都可能出現讀取漢字輸出亂碼的問題
可以將文件的全部字節讀取后,再整體解碼出內容。
java官方為InputStream提供了如下方法,可以直接把文件的全部字節讀取到一個字節數組中返回

以內存為基準,把內存中的數據以字節的形式寫出到文件中去。
常用方法:

public static void main(String[] args) throws Exception {
// 1、創建一個字節輸出流管道與目標文件接通。
// 覆蓋管道:覆蓋之前的數據
// OutputStream os =
// new FileOutputStream("file-io-app/src/itheima04out.txt");
// 追加數據的管道
OutputStream os =
new FileOutputStream("test1.txt", true);
// 2、開始寫字節數據出去了
os.write(97); // 97就是一個字節,代表a
os.write('b'); // 'b'也是一個字節
// os.write('磊'); // [ooo] 默認只能寫出去一個字節
byte[] bytes = "我愛你中國abc".getBytes();
os.write(bytes);
os.write(bytes, 0, 15);
// 換行符
os.write("\r\n".getBytes());
os.close(); // 關閉流
}
釋放資源的方式
try-catch-finally
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
System.out.println(10 / 0);
// 1、創建一個字節輸入流管道與源文件接通
is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2、創建一個字節輸出流管道與目標文件接通。
os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");
System.out.println(10 / 0);
// 3、創建一個字節數組,負責轉移字節數據。
byte[] buffer = new byte[1024]; // 1KB.
// 4、從字節輸入流中讀取字節數據,寫出去到字節輸出流中。讀多少寫出去多少。
int len; // 記住每次讀取了多少個字節。
while ((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}
System.out.println("復制完成!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 釋放資源的操作
try {
if(os != null) os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意:鼠標劃選住try后的代碼,再按ctrl+alt+t將可以快速寫try-catch-finally

public static void main(String[] args) {
try (
// 1、創建一個字節輸入流管道與源文件接通
InputStream is = new FileInputStream("D:/resource/meinv.png");
// 2、創建一個字節輸出流管道與目標文件接通。
OutputStream os = new FileOutputStream("C:/data/meinv.png");
){
// 3、創建一個字節數組,負責轉移字節數據。
byte[] buffer = new byte[1024]; // 1KB.
// 4、從字節輸入流中讀取字節數據,寫出去到字節輸出流中。讀多少寫出去多少。
int len; // 記住每次讀取了多少個字節。
while ((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}
System.out.println(conn);
System.out.println("復制完成!!");
} catch (Exception e) {
e.printStackTrace();
}
}
注意:
try()的括號里只能放資源對象(流對象)
資源都會實現AutoCloseable接口
以內存為基準,可以把文件中的數據以字符的形式讀入到內存中去
常用方法:

public static void main(String[] args) {
try (
// 1、創建一個文件字符輸入流管道與源文件接通
Reader fr = new FileReader("io-app2\\src\\itheima01.txt");
){
// 2、一個字符一個字符的讀(性能較差)
// int c; // 記住每次讀取的字符編號。
// while ((c = fr.read()) != -1){
// System.out.print((char) c);
// }
// 每次讀取一個字符的形式,性能肯定是比較差的。
// 3、每次讀取多個字符。(性能是比較不錯的!)
char[] buffer = new char[3];
int len; // 記住每次讀取了多少個字符。
while ((len = fr.read(buffer)) != -1){
// 讀取多少倒出多少
System.out.print(new String(buffer, 0, len));
}
} catch (Exception e) {
e.printStackTrace();
}
}
以內存為基準,把內存中的數據以字符的形式寫出到文件中去。
常用方法:

public static void main(String[] args) {
try (
// 0、創建一個文件字符輸出流管道與目標文件接通。
// 覆蓋管道
// Writer fw = new FileWriter("io-app2/src/itheima02out.txt");
// 追加數據的管道
Writer fw = new FileWriter("io-app2/src/itheima02out.txt", true);
){
// 1、public void write(int c):寫一個字符出去
fw.write('a');
fw.write(97);
//fw.write('磊'); // 寫一個字符出去
fw.write("\r\n"); // 換行
// 2、public void write(String c)寫一個字符串出去
fw.write("我愛你中國abc");
fw.write("\r\n");
// 3、public void write(String c ,int pos ,int len):寫字符串的一部分出去
fw.write("我愛你中國abc", 0, 5);
fw.write("\r\n");
// 4、public void write(char[] buffer):寫一個字符數組出去
char[] buffer = {'黑', '馬', 'a', 'b', 'c'};
fw.write(buffer);
fw.write("\r\n");
// 5、public void write(char[] buffer ,int pos ,int len):寫字符數組的一部分出去
fw.write(buffer, 0, 2);
fw.write("\r\n");
} catch (Exception e) {
e.printStackTrace();
}
}
注意:
字符輸出流寫出數據后,必須刷新流,或者關閉流,寫出去的數據才能生效 (字符是先寫到緩沖區的)
緩沖流作用:對原始流進行包裝,以提高原始流讀寫數據的性能。

字節緩沖流原理:字節緩沖輸入流自帶了8KB緩沖池;字節緩沖輸出流也自帶了8KB緩沖池。流先將數據寫入緩沖區,再在內存中進行讀寫。

常用方法:

public static void main(String[] args) {
try (
InputStream is = new FileInputStream("io-app2/src/itheima01.txt");
// 1、定義一個字節緩沖輸入流包裝原始的字節輸入流
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream("io-app2/src/itheima01_bak.txt");
// 2、定義一個字節緩沖輸出流包裝原始的字節輸出流
OutputStream bos = new BufferedOutputStream(os);
){
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(buffer, 0, len);
}
System.out.println("復制完成!!");
} catch (Exception e) {
e.printStackTrace();
}
}
作用:自帶8K (8192)的字符緩沖池,可以提高字符輸入流讀取字符數據的性能。
常用方法:

新增方法:

public static void main(String[] args) {
try (
Reader fr = new FileReader("io-app2\\src\\itheima04.txt");
// 創建一個字符緩沖輸入流包裝原始的字符輸入流
BufferedReader br = new BufferedReader(fr);
){
// char[] buffer = new char[3];
// int len;
// while ((len = br.read(buffer)) != -1){
// System.out.print(new String(buffer, 0, len));
// }
// System.out.println(br.readLine());
// System.out.println(br.readLine());
// System.out.println(br.readLine());
// System.out.println(br.readLine());
String line; // 記住每次讀取的一行數據
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
常用方法:

public static void main(String[] args) {
try (
Writer fw = new FileWriter("io-app2/src/itheima05out.txt", true);
// 創建一個字符緩沖輸出流管道包裝原始的字符輸出流
BufferedWriter bw = new BufferedWriter(fw);
){
bw.write('a');
bw.write(97);
bw.write('磊');
bw.newLine();
bw.write("我愛你中國abc");
bw.newLine();
} catch (Exception e) {
e.printStackTrace();
}
}
問題:如果代碼編碼和被讀取的文本文件的編碼是不一致的,使用字符流讀取文本文件時就會出現亂碼!
解決不同編碼時,字符流讀取文本內容亂碼的問題。
解決思路:先獲取文件的原始字節流,再將其按真實的字符集編碼轉成字符輸入流,這樣字符輸入流中的字符就不亂碼了。
常用方法:

public static void main(String[] args) {
try (
// 1、得到文件的原始字節流(GBK的字節流形式)
InputStream is = new FileInputStream("io-app2/src/itheima06.txt");
// 2、把原始的字節輸入流按照指定的字符集編碼轉換成字符輸入流
Reader isr = new InputStreamReader(is, "GBK");
// 3、把字符輸入流包裝成緩沖字符輸入流
BufferedReader br = new BufferedReader(isr);
){
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
可以控制寫出去的字符使用什么字符集編碼。
解決思路:獲取字節輸出流,再按照指定的字符集編碼將其轉換成字符輸出流,以后寫出去的字符就會用該字符集編碼了
常用方法:

public static void main(String[] args) {
// 指定寫出去的字符編碼。
try (
// 1、創建一個文件字節輸出流
OutputStream os = new FileOutputStream("io-app2/src/itheima07out.txt");
// 2、把原始的字節輸出流,按照指定的字符集編碼轉換成字符輸出轉換流。
Writer osw = new OutputStreamWriter(os, "GBK");
// 3、把字符輸出流包裝成緩沖字符輸出流
BufferedWriter bw = new BufferedWriter(osw);
){
bw.write("我是中國人abc");
bw.write("我愛你中國123");
} catch (Exception e) {
e.printStackTrace();
}
}
作用:打印流可以實現更方便、更高效的打印數據出去,能實現打印啥出去就是啥出去。(是寫數據出去的意思)
常用方法:

public static void main(String[] args) {
try (
// 1、創建一個打印流管道
// PrintStream ps =
// new PrintStream("io-app2/src/itheima08.txt", Charset.forName("GBK"));
// PrintStream ps =
// new PrintStream("io-app2/src/itheima08.txt");
PrintWriter ps =
new PrintWriter(new FileOutputStream("io-app2/src/itheima08.txt", true));
){
ps.print(97); //文件中顯示的就是:97
ps.print('a'); //文件中顯示的就是:a
ps.println("我愛你中國abc"); //文件中顯示的就是:我愛你中國abc
ps.println(true);//文件中顯示的就是:true
ps.println(99.5);//文件中顯示的就是99.5
ps.write(97); //文件中顯示a,發現和前面println方法的區別了嗎?
} catch (Exception e) {
e.printStackTrace();
}
}
與PrintStream 類似。
常用方法:

應用場景:將輸入控制臺的信息輸入到文件中
public static void main(String[] args) {
System.out.println("老驥伏櫪");
System.out.println("志在千里");
try ( PrintStream ps = new PrintStream("io-app2/src/itheima09.txt"); ){
// 把系統默認的打印流對象改成自己設置的打印流
System.setOut(ps);
System.out.println("烈士暮年");
System.out.println("壯心不已");
} catch (Exception e) {
e.printStackTrace();
}
}
允許把數據和其類型一并寫出去。
常用方法:

public static void main(String[] args) {
try (
// 1、創建一個數據輸出流包裝低級的字節輸出流
DataOutputStream dos =
new DataOutputStream(new FileOutputStream("io-app2/src/itheima10out.txt"));
){
dos.writeInt(97);
dos.writeDouble(99.5);
dos.writeBoolean(true);
dos.writeUTF("黑馬程序員666!");
} catch (Exception e) {
e.printStackTrace();
}
}
用于讀取數據輸出流寫出去的數據。
常用方法:

public static void main(String[] args) {
try (
DataInputStream dis =
new DataInputStream(new FileInputStream("io-app2/src/itheima10out.txt"));
){
int i = dis.readInt();
System.out.println(i);
double d = dis.readDouble();
System.out.println(d);
boolean b = dis.readBoolean();
System.out.println(b);
String rs = dis.readUTF();
System.out.println(rs);
} catch (Exception e) {
e.printStackTrace();
}
}
對象序列化: 把java對象寫入到文件中去。
對象反序列化: 把文件里的Java對象讀出來。
可以把Java對象進行序列化: 把Java對象存入到文件中去。
常用方法:

public static void main(String[] args) {
try (
// 2、創建一個對象字節輸出流包裝原始的字節 輸出流。
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("io-app2/src/itheima11out.txt"));
){
// 1、創建一個Java對象。
User u = new User("admin", "張三", 32, "666888xyz");
// 3、序列化對象到文件中去
oos.writeObject(u);
System.out.println("序列化對象成功!!");
} catch (Exception e) {
e.printStackTrace();
}
}
注意:其中的User對象必須讓其實現Serializable接口。
可以把Java對象進行反序列化: 把存儲在文件中的Java對象讀入到內存中來。
常用方法:

public static void main(String[] args) {
try (
// 1、創建一個對象字節輸入流管道,包裝 低級的字節輸入流與源文件接通
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io-app2/src/itheima11out.txt"));
){
User u = (User) ois.readObject();
System.out.println(u);
} catch (Exception e) {
e.printStackTrace();
}
}
如果想讓對象的某個字段不被序列化,可以添加transient修飾。
public class User implements Serializable {
private String loginName;
private String userName;
private int age;
// transient 這個成員變量將不參與序列化。
private transient String passWord;
}
O框架:封裝了Java提供的對文件、數據進行操作的代碼,對外提供了更簡單的方式來對文件進行操作,對數據進行讀寫等。
框架的形式:一般是把類、接口等編譯成class形式,再壓縮成一個jar結尾的文件發行出去
Commons-io是apache開源基金組織提供的一組有關IO操作的小框架,目的是提高IO流的開發效率。
常用方法:

