1.流的概念与分类
1.1概念
概念:内存与存储设备之间传输数据的通道。
1.2分类
- 按方向【重点】
- 输入流:将存储设备中的内容读入到内存中
- 输出流:将内存中的内容写入到存储设备中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iffNlDcp-1642148739563)(…/AppData/Roaming/Typora/typora-user-images/image-20220108204025495.png)]
-
按单位
- 字节流:以字节为单位。可以读写所有数据(因为所有数据都以字节形式存储)
- 字符流:以字符为单位,只能读写文本数据
-
按功能
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础之上增强功能
2.字节流
- 字节流的父类(抽象类)
- InputStream:字节输入流
- OutputStream:字节输出流
因为父类数抽象类,要使用时必须用其子类。
2.1文件字节流
- FileInputStream:—实现了InputStream抽象类
- public int read(byte[] b)//从流中读取多个字节,将读取到的内容存到b数组,返回实际读取到的字节数;如果达到文件的尾部,则返回-1
- 构造方法:传入文件名路径
- FileOutputStream:—实现了OutputStream抽象类
- public void write(byte[] b)//一次写多个字节,将b数组中所有字节,写入输出流。
(1)文件字节输入流案例:
package com.song.demo01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
//FileInputStream类,文件字节输入流
public class demo01 {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
//2.读取文件
//2.1单个字节读取
//fis.read()每次只能读取一个字节(读出的是字符对应的Ascii编码),读到结尾返回-1
/*int data = 0;
while ((data = fis.read()) != -1) {
System.out.println((char) data);
}*/
//2.2一次读取多个字节(文件写入abcdefgh)
/*byte[] b1 = new byte[3];
int count1 = fis.read(b1);//返回的是实际读取的个数
System.out.println(count1);
System.out.println(new String(b1));//abc
byte[] b2 = new byte[5];
int count2 = fis.read(b2);//返回的是实际读取的个数
System.out.println(count2);
System.out.println(new String(b2));//defgh
*/
//用循环实现
byte[] b = new byte[3];
int count = 0;
while ((count = fis.read(b)) != -1) {
System.out.println(new String(b, 0, count));
}
//三次abc,def,gh
//3.关闭
fis.close();
}
}
(2)文件字节输出流案例:
package com.song.demo01;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//FileOutputStream文件字节输出流
public class demo02 {
public static void main(String[] args) throws IOException {
//1.创建文件字节流出对象
FileOutputStream fos = new FileOutputStream("d://bbb.txt");//每次回覆盖原有
//FileOutputStream fos = new FileOutputStream("d://bbb.txt", true);//append=true,表示会追加,不会覆盖原来
//2.写入文件
//2.1单个写入
/*fos.write(97);//写的是Asci对应的字符
fos.write('b');
fos.write('c');*/
//2.2一次性写入
String str = "Hello World!";
fos.write(str.getBytes());//获得字符串对应的字节数组,再进行写入
//3.关闭
fos.close();
}
}
(3)文件复制的案例:
package com.song.demo01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//使用字节流实现文件复制
public class demo03 {
public static void main(String[] args) throws IOException {
//1.创建流
//1.1文件字节输入流
FileInputStream fis = new FileInputStream("d://a.jpg");
//1.2文件字节输出流
FileOutputStream fos = new FileOutputStream("d://b.jpg");
//2.一边读一边写
byte[] buf = new byte[1024];//1KB 的缓冲区
int count = 0;//保存实际读取的字节数
while ((count = fis.read(buf)) != -1) {
fos.write(buf, 0, count);
}
//3.关闭
fis.close();
fos.close();
System.out.println("复制关闭");
}
}
2.2字节缓冲流
缓冲流:BufferInputStream/BufferOutputStream
- 提高IO效率,减少访问磁盘的次数
- 数据存储在缓冲区,flush是将缓存区的内容写入文件中,也可以直接close
- 缓冲流内部本质维护的是字节流
(文件字节流的效率低,字节缓冲区效率更高)
(1)使用字节缓冲流读取文件案例
package com.song.demo01;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class demo04 {
public static void main(String[] args) throws IOException {
//1.创建BufferInputStream
//带缓冲的字节输入流
FileInputStream fis = new FileInputStream("d:\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//2.读取
//用系统自带的缓冲区8KB
/*int data = 0;
//bis的一次读取,能读取缓存8KB,下次再读直接从缓冲区内读
while ((data = bis.read()) != -1) {
System.out.print((char) data);
}*/
//自定义缓冲区
byte[] buf = new byte[1024];//1KB的缓冲区
int count = 0;
while ((count = bis.read(buf)) != -1) {
System.out.println(new String(buf, 0, count));
}
//3.关闭(关闭缓冲流即可,可以同时把字节流关闭)
bis.close();
}
}
(2)使用字节缓冲流写入文件案例
package com.song.demo01;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class demo05 {
public static void main(String[] args) throws IOException {
//1.创建BufferedOutputStream
//可以先写到一个缓冲区,再flush到底层,不必每次都写入底层
FileOutputStream fos = new FileOutputStream("d:\\buffer.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//2.写入文件
//8KB的缓冲区
for (int i = 0; i < 10; i++) {
bos.write("Hello World!\n".getBytes());//此处只是写入到缓冲区中,并未直接写入文件
bos.flush();//刷新写入到硬盘
}
//3.关闭(内部会调用flush)
bos.close();
}
}
2.3对象流
对象流:ObjectOutputStream/ObjectInputStream
对象流是过滤流,要使用之前先创建节点流。
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象的功能
- readObject() 从流中读取一个对象
- writeObject(Object obj)向流中写入一个对象
使用流传输对象的过程称为序列化、反序列化。
(1)序列化
- 要求:序列化的类必须实现Serializable接口
- 使用ObjectOutputStream实现序列化(写入一个对象)
package com.song.demo01;
import java.io.Serializable;
//对象要想序列化,类必须实现一个接口Serializable---仅仅标记该类可以序列化
public class Student implements Serializable {
//serialVersionUID:序列化版本号ID,作用:保证序列化的类和反序列化的类是同一个类。
private static final long serialVersionUID = 100L;
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.song.demo01;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
//使用ObjectOutputStream实现对象序列化
//要求:对象要想序列化,类必须实现一个接口Serializable
public class demo06 {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileOutputStream fos = new FileOutputStream("d:\\student.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2.实现序列化(写入操作)
//要求:对象要想序列化,类必须实现一个接口Serializable
Student zhangsan = new Student("zhangsan", 20);
oos.writeObject(zhangsan);//将一个对象写入
//3.关闭(clos会自动调用flush)
oos.close();
System.out.println("序列化完毕");
}
}
(2)反序列化
- 使用ObjectInputStream实现反序列化–从文件中读取内容再重新构成对象
package com.song.demo01;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
//使用ObjectInputStream实现反序列化
public class demo07 {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileInputStream fis = new FileInputStream("d:\\student.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.读取文件(反序列化)
Student student = (Student) ois.readObject();//强转换一下
System.out.println(student.toString());
//3.关闭
ois.close();
System.out.println("反序列化完毕");
}
}
(3)序列化与反序列化的注意事项
-
序列化的类必须实现Serializable接口
-
序列化的类中的对象属性(类)也要求实现Serializable接口
-
serialVersionUID:序列化版本号ID,作用:保证序列化的类和反序列化的类是同一个类。(要保证序列化时就已经添加该ID)
-
使用transient(瞬间瞬时)修饰属性,这个属性就不能序列化
private transient int age;//该属性不能被序列化
-
静态属性(static)也是不能被序列化的
-
序列化多个对象时,可以借助集合来实现----ArrayList
package com.song.demo01;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
//使用ObjectOutputStream实现对象序列化
//要求:对象要想序列化,类必须实现一个接口Serializable
public class demo06 {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileOutputStream fos = new FileOutputStream("d:\\student.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2.实现序列化(写入操作)
//要求:对象要想序列化,类必须实现一个接口Serializable
Student zhangsan = new Student("zhangsan", 20);
Student lisi = new Student("lisi", 22);
ArrayList<Student> list = new ArrayList<>();
list.add(zhangsan);
list.add(lisi);
oos.writeObject(list);//将一个对象写入
//3.关闭(clos会自动调用flush)
oos.close();
System.out.println("序列化完毕");
}
}
package com.song.demo01;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Arrays;
//使用ObjectInputStream实现反序列化
public class demo07 {
public static void main(String[] args) throws Exception {
//1.创建对象流
FileInputStream fis = new FileInputStream("d:\\student.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.读取文件(反序列化)
ArrayList<Student> list = (ArrayList<Student>) ois.readObject();//强转换一下
System.out.println(list.toString());
//3.关闭
ois.close();
System.out.println("反序列化完毕");
}
}
4.字符编码方式
-
ISO-8859-1:采用一个字节表示,最多只能256个字符
-
UTF-8:国际上通用,采用1或2或3个字节表示
-
GB2312:中文,采用1或2个字节表示
-
GBK:是国标2312的升级,采用1或2个字节表示
当编码方式与解码方式不一致,会出现乱码!注意保持一致。
4.字符流
实例:(使用字节流读取中文字符出现问题)
package com.song.demo02;
import java.io.FileInputStream;
//使用文件字节输入流读取一个对象
public class demo01 {
public static void main(String[] args) throws Exception {
//1.创建FileInputStream对象
FileInputStream fis = new FileInputStream("d:\\aaa.txt");//文件中:好好学习
//2.读取
int data = 0;
while ((data = fis.read()) != -1) {//文件中12个字节4个汉字;而此处read是读取一个一个的字节,变成字符,故出现问题
System.out.print((char) data);//直接读取中文,出现乱码
}
//3.关闭
fis.close();
}
}
字符流的父类(抽象类)
- Reader:字符输入流
- Writer:字符输出流
因为父类数抽象类,要使用时必须用其子类。
4.1文件字符流
- FileReader:
- public int read(char[] c)//从流中读取多个字符,将读到的内容存入c数组,返回实际读取到的字符数;如果到达文件的尾部,则返回-1。
- FileReader类的构造方法假定默认字符编码和字节缓冲区大小都是适当的,若要自己指定这些值,可以现在FileInputStream上构造一个InputStreamReader。
- FileWriter:
- public void write(String str)//一次写入多个字符,将b数组中的所有字符,写入输出流。
(1)文件字符输入流
package com.song.demo02;
import java.io.FileReader;
public class demo02 {
public static void main(String[] args) throws Exception {
//1.创建文件字符输出流FileReader
FileReader fr = new FileReader("d:\\aaa.txt");
//2.读取
//2.1单个字符读取
/*int data = 0;
while ((data = fr.read()) != -1) {//此处read读取的的是一个字符,而非一个字节,可能对应的是三个字节
System.out.print((char) data);
}*/
//2.2通过字符缓冲区一次读取多个字符
char[] buf = new char[1024];//创建1K的缓冲区,此处是字符数组,不是字节数组,注意区分!!
int count = 0;
while ((count = fr.read(buf)) != -1) {
System.out.println(new String(buf, 0, count));
}
//3.关闭
fr.close();
}
}
(2)文件字符输出流
package com.song.demo02;
import java.io.FileWriter;
public class demo03 {
public static void main(String[] args) throws Exception {
//1.创建文件字符输出流对象FileWriter
FileWriter fw = new FileWriter("d:\\test.txt");
//2.写入
for (int i = 0; i < 10; i++) {
fw.write("Java 是世界上最好的语言!!\n");
fw.flush();
}
//3.关闭
fw.close();
}
}
(3)使用文件字符流实现文件复制
package com.song.demo02;
import java.io.FileReader;
import java.io.FileWriter;
//使用文件字符流实现文件复制--只能复制文本文件,不能复制图片等二进制文件
public class demo04 {
public static void main(String[] args) throws Exception {
//1.创建流
FileReader fr = new FileReader("d:\\test.txt");
FileWriter fw = new FileWriter("d:\\test2.txt");
//2.读取和写入
int data = 0;
while ((data = fr.read()) != -1) {
fw.write(data);
}
//3.关闭
fr.close();
fw.close();
System.out.println("复制完毕");
}
}
字符流只能用于文本文件,不能用于图片等二进制文件。
图片并没有编码,编码成字符写入,是一堆乱码。故字符流不能复制没有字符编码的文件。
使用字节流可以复制任何文件,因为在硬盘上所有文件都以二进制形式存储。
4.2字符缓冲流
缓冲流:BufferReader/BufferWriter
- 高效读写
- 支持输入换行
- 可一次写一行、读一行
(1)使用字符缓冲流读取
package com.song.demo02;
import java.io.BufferedReader;
import java.io.FileReader;
//使用字符缓冲流读取文件
public class demo05 {
public static void main(String[] args) throws Exception {
//1.创建字符缓冲流
FileReader fr = new FileReader("d:\\test.txt");
BufferedReader br = new BufferedReader(fr);
//2.读取
//2.1第一种方式
/*char[] buf=new char[1024];
int count=0;
while((count=br.read(buf))!=-1){
System.out.print(new String(buf,0,count));
}*/
//2.2一行一行的读取
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//3.关闭
br.close();
}
}
(2)使用字符缓冲流写入
package com.song.demo02;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
//使用字符缓冲流写入文件
public class demo06 {
public static void main(String[] args) throws Exception {
//1.创建对象
FileWriter fw = new FileWriter("d:\\tt.txt");
BufferedWriter bw = new BufferedWriter(fw);
//2.写入
for (int i = 0; i < 10; i++) {
bw.write("好好学习,天天向上");//未换行
bw.newLine();//写入一个换行符\r\n
bw.flush();
}
//3.关闭
bw.close();
System.out.println("执行完毕");
}
}
5.打印流
PrintWriter–继承了Writer类:
- 封装了print() 、println()方法,支持写入后换行
- 支持数据原样打印—支持的数据类型更丰富
package com.song.demo02;
import java.io.PrintWriter;
//PrintWrite
public class demo07 {
public static void main(String[] args) throws Exception {
//1.创建打印流
PrintWriter pw = new PrintWriter("d:\\print.txt");
//2.打印
pw.println(97);
pw.println(true);
pw.println(3.14);
pw.println('a');
//3.关闭
pw.close();
}
}
6.转换流
- 桥转换流:InputStreamReader/OutputStreamWriter
- 可以将字节流转换为字符流;字符流转成字节流(内存中的字符与硬盘中的字节之间的转换)
- 可以设置字符的编码方式。
(1)InputStreamReader读取文件
- 字节流转成字符流
- InputStreamReader实际就是字节流的抽象类与字符流的抽象类合在一起。
package com.song.demo02;
import java.io.FileInputStream;
import java.io.InputStreamReader;
//InputStreamReader读取文件,可以指定使用的编码
public class demo08 {
public static void main(String[] args) throws Exception {
//1.创建对象
FileInputStream fis = new FileInputStream("d:\\test.txt");
InputStreamReader isr = new InputStreamReader(fis, "utf-8");//文件实际就是utf-8的编码方式;
//要保证文件编码与使用的转换流编码一致
//FileReader不能指定编码;InputStreamReader可以指定编码
//2.读取文件
int data = 0;
while ((data = isr.read()) != -1) {
System.out.print((char) data);
}
//3.关闭
isr.close();
}
}
(2)OutputStreamWriter写入文件
- 字符流转成字节流
- OutputStreamWriter实际就是字节流的抽象类与字符流的抽象类合在一起。
package com.song.demo02;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
//使用OutputStreamWriter写入文件
public class demo09 {
public static void main(String[] args) throws Exception {
//1.创建流
FileOutputStream fos = new FileOutputStream("d:\\test3.txt");//字节输出流
OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk");//自定义编码
//2.写入
for (int i = 0; i < 10; i++) {
osw.write("好好学习呀呀呀!\n");
osw.flush();
}
//3.关闭
osw.close();
}
}
7.File类
与文件读写相关的操作可以借助流,其他类似删除、时间等操作要借助File类
概念:代表物理盘符中的一个文件或者文件夹。
File类是文件和目录名的抽象表现方式。
7.1文件操作与文件夹操作
package com.song.demo02;
import java.io.File;
import java.util.Date;
/**
* File类的使用:
* (1)分隔符
* (2)文件操作
* (3)文件夹操作
*/
public class demo10 {
public static void main(String[] args) throws Exception {
separator();
fileOpe();
directorOpe();
}
//(1)分隔符
public static void separator() {
System.out.println("路径分隔符:" + File.pathSeparator);// ;
System.out.println("名称分隔符:" + File.separator);// \
}
//(2)文件操作
public static void fileOpe() throws Exception {
//1.创建文件
//1.1创建文件对象
File file = new File("d:\\file.txt");//实际硬盘中并不一定存在该文件
//1.2在硬盘上创建文件
if (!file.exists()) {
boolean b = file.createNewFile();//文件存在则不创建;不存在则创建
System.out.println("创建结果:" + b);
}
//2.删除文件
/*
//2.1直接删除
System.out.println("删除结果:" + file.delete());
//2.2使用JVM退出时删除
file.deleteOnExit();//只有JVM退出时才删除
Thread.sleep(5000);*/
//3.获取文件信息
//3.1获取文件的绝对路径
System.out.println("获取文件的绝对路径:" + file.getAbsolutePath());
//3.2获取路径
System.out.println("获取路径:" + file.getPath());//与自定义的路径有关,写的是绝对路径就用绝对路径;写的是相对路径就用相对路径
//3.3获取文件名称
System.out.println("获取文件名称:" + file.getName());
//3.4获取父目录
System.out.println("获取文件父目录:" + file.getParent());
//3.5获取文件长度
System.out.println("获取文件长度:" + file.length());
//3.6获取文件创建时间
System.out.println("获取文件创建时间:" + new Date(file.lastModified()).toLocaleString());
//4.判断
System.out.println("判断文件是否可写:" + file.canWrite());
System.out.println("判断是否是文件:" + file.isFile());
System.out.println("文件是否隐藏:" + file.isHidden());
}
//(2)文件夹操作
public static void directorOpe() throws Exception {
//1.创建文件夹
File dir = new File("d:\\a\\b\\c");
if (!dir.exists()) {
//dir.mkdir();//只能创建单级目录
//dir.mkdirs();//可以创建多级目录
System.out.println("创建结果:" + dir.mkdirs());
}
//2.删除文件夹
/*
//2.1直接删除
System.out.println("删除结果:" + dir.delete());//并非全删除,是只删除最底层的c目录,且要求c必须为空目录!
//2.2使用JVM删除
dir.deleteOnExit();*/
//3.获取文件夹信息
System.out.println("获取绝对路径" + dir.getAbsolutePath());
System.out.println("获取路径" + dir.getPath());
System.out.println("获取文件夹名称" + dir.getName());//仅仅最底层
System.out.println("获取父目录" + dir.getParent());
System.out.println("获取创建时间" + new Date(dir.lastModified()).toString());
//4.判断
System.out.println("判断是否是文件夹" + dir.isDirectory());
System.out.println("判断是否是隐藏的" + dir.isHidden());
//5.遍历文件夹
File dir2 = new File("d:\\software");
String[] files = dir2.list();
for (String str : files) {
System.out.println(str);
}
}
}
7.2FileFilter接口
-
public interface FileFilter
- boolean accept(File pathname)
-
当调用File类中的listFiles()方法时,支持传入FileFilter接口实现类,对获取文件进行过滤,只有满足条件的文件才可以出现在listFiles()的返回值中。
//FileFilter的使用
//注意此处是File[] 集合
File[] files2 = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
//return false;//默认为false,所有文件全部去掉
if (pathname.getName().endsWith(".jpg")) {
return true;//只保留jpg文件
}
return false;
}
});
for (File file : files2) {
System.out.println(file.getName());
}
7.3递归遍历和递归删除
(1)递归遍历文件夹
package com.song.demo02;
import java.io.File;
//案例一:递归遍历文件夹
public class demo11 {
public static void main(String[] args) {
File dir = new File("d:\\software");
listDir(dir);
}
public static void listDir(File dir) {
File[] files = dir.listFiles();
System.out.println(dir.getAbsolutePath());
if (files != null && files.length > 0) {
for (File file : files) {
if (file.isDirectory()) {
listDir(file);//递归
} else {
System.out.println(file.getName());
}
}
}
}
}
(2)递归删除文件夹
package com.song.demo02;
import java.io.File;
//案例二:递归删除文件夹
public class demo12 {
public static void main(String[] args) {
delDir(new File("d:\\a"));
}
public static void delDir(File dir) {
File[] files = dir.listFiles();
if (files != null && files.length > 0) {
for (File file : files) {
if (file.isDirectory()) {
delDir(file);
} else {
//删除文件
System.out.println(file.getAbsolutePath() + "删除:" + file.delete());
}
}
//删除文件夹
System.out.println(dir.getAbsolutePath() + "删除:" + dir.delete());
}
}
}
补充:Properities
- Properities:属性集合
- 特点:
- 存储属性名和属性值
- 属性名和属性值都是字符串类型
- 没有泛型
- 和流有关
package com.song.demo02;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;
//Properities集合的使用
public class demo13 {
public static void main(String[] args) throws Exception {
//1.创建集合
Properties properties = new Properties();
//2.添加数据
properties.setProperty("name", "zhangsan");
properties.setProperty("age", "18");
System.out.println(properties.toString());
//3.遍历
//3.1----keyset---
//3.2----entryset---
//3.3----stringPropertyNames---
Set<String> pronames = properties.stringPropertyNames();
for (String pro : pronames) {
System.out.println(pro + "====" + properties.getProperty(pro));
}
//4.和流有关的方法
//4.1----list----
/*PrintWriter pw = new PrintWriter("d:\\print2.txt");
properties.list(pw);
pw.close();*/
//4.2----store---保存
/*FileOutputStream fos = new FileOutputStream("d:\\store.properites");
properties.store(fos, "注释");
fos.close();*/
//4.3----load---加载
Properties properties2 = new Properties();
FileInputStream fis = new FileInputStream("d:\\\\store.properites");
properties2.load(fis);
fis.close();
System.out.println(properties.toString());
}
}
总结
-
流的概念:
内存和存储设备之间传输数据的通道
-
流的分类:
输入流、输出流;字节流、字符流;节点流、过滤流
-
序列化和反序列化
内存中的对象通过流写入硬盘文件中—序列化
硬盘文件中的对象通过流读取到内存中—反序列化
-
File类
代表物理盘符中的为一个文件或者文件夹