一、IO
1.1 概述
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
I : input 输入
O : output 输出
1.2 分类
按处理数据类型的不同,分为字节流和字符流
按数据流向的不同,分为输入流和输出流。(入和出是相对于内存来讲的)
按功能不同,分为节点流和处理流
- 节点流:直接操作数据源
- 处理流:对其他流进行处理
1.3 四大抽象类
1.3.1 InputStream
1.3.2 OutputStream
1.3.3 Reader
1.3.4 Writer
1.4 文件流
文件流:用于打开文件链接,操作数据
FileInputStream 字节输入
FileOutputStream 字节输出
FileReader 字符输入
FileWriter 字符输出
1.4.1 FileInputstream
1.4.1.1 概述
FileInputstream 字节输入流,用于把某个文件已字节的形式读取出来
想要读取一个文件,首先得找到这个文件
怎么找呢? 1 相对路径 2 绝对路径
相对路径:以当前文件为准,去找其他文件, ./表示当前目录, …/表示上级目录, …/…/
绝对路径:以系统跟盘符为准,比如D盘 E盘
1.4.1.2 常用方法
1.4.1.3 Read使用
1.4.1.4 Read重载使用
1.4.2 FileReader
1.4.2.1 概述
FileReader一次读取一个字符,也就是两字节,而Unicode编码也是2字节
所以 读取文本文件时,不会出现乱码问题
1.4.2.2 使用方式
1.4.3 FileOutputstream
1.4.3.1 概述
FileOutputstream 是字节输出流,用于将内存中数据写出去
需要传入文件路径,如果该文件不存在,则会自动创建(但是不会创建目录)
1.4.3.2 常用方法
1.4.3.3 使用方式
1.4.4 FileWriter
1.5 缓冲流
特点:
- 主要是为了提高效率而存在的,减少物理读取次数
- 提供readLine()、newLine()这样的便捷的方法(针对缓冲字符流)
- 在读取和写入时,会有缓存部分,调用flush为刷新缓存,将内存数据写入到磁盘
1.5.1 BufferedReader
1.5.2 BufferedWriter
1.6 转换流
1.6.1 InputStreamReader
1.6.2 OutputStreamWriter
1.6.3 处理乱码问题
1.7 打印流
1.7.1 概述
1.7.2 使用方式
1.8 数据流
1.8.1 概述
数据 --> 加密 --> 传递 --> 读取 --> 解密 --> 数据
1.8.2 使用
二、File
2.1 概述
2.2 构造方法
public File(String pathname)以pathname为路径创建File对象,可以是绝对路径或者相对路
径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
绝对路径:是一个固定的路径,从盘符开始
相对路径:是相对于某个位置开始
public File(String parent,String child)以parent为父路径,child为子路径创建File对象。
public File(File parent,String child)根据一个父File对象和子文件路径创建File对象
2.3 常用方法
获取功能:
public String getAbsolutePath():获取绝对路径
public String getPath() :获取路径
public String getName() :获取名称
public String getParent():获取上层文件目录路径。若无,返回null
public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
public long lastModified() :获取最后一次的修改时间,毫秒值
public String[] list() :获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles() :获取指定目录下的所有文件或者文件目录的File数组
重命名功能:
public boolean renameTo(File dest):把文件重命名为指定的文件路径
判断功能:
public boolean isDirectory():判断是否是文件目录
public boolean isFile() :判断是否是文件
public boolean exists() :判断是否存在
public boolean canRead() :判断是否可读
public boolean canWrite() :判断是否可写
public boolean isHidden() :判断是否隐藏
创建删除功能:
public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false
public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。 如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建
注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目 路径下。
public boolean delete():删除文件或者文件夹
删除注意事项:
Java中的删除不走回收站。
要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
2.4 使用方式
// 创建对象
File file = new File("E:/com/a.txt");
// 获取全路径
System.out.println(file.getAbsolutePath());
// 获取文件名,包括扩展名
// 目录只获取目录名字, 如果是文件 则获取文件名+扩展名
System.out.println(file.getName());
// 获取父路径(上级目录)
String parentPath = file.getParent();
System.out.println(parentPath);
// 获取父(上级) 对象
File parentFile = file.getParentFile();
// 判断是否是文件,如果文件不存在,也是false
System.out.println(file.isFile());
// 判断是否是目录
System.out.println(file.isDirectory());
// 获取最后一次修改时间,返回毫秒数
long timer = file.lastModified();
System.out.println(new Date(timer));
// 判断是否存在
System.out.println(file.exists());
// 创建文件,返回布尔型,true,表示创建好了,false表示没有创建
// 只创建文件,不会创建目录
System.out.println(file.createNewFile());
// 删除,成功返回true
System.out.println(file.delete());
File f1 = new File("E:/a/b/c");
// 创建目录,只会创建c,a和b不会创建
System.out.println(f1.mkdir());
// 会创建所有目录
System.out.println(f1.mkdirs());
// 得是目录才行
f1 = new File("E:/a/b/c/d.txt");
// 如果想要创建d.txt对应的目录,不能直接创建,否则会把d.txt也当成目录
// f1.mkdirs();
// 需要先获取父目录,对父目录进行创建
File f2 = f1.getParentFile();
if (!f2.exists()) {
f2.mkdirs();
}
f1.createNewFile();
2.5 递归复制
2.5.1 获取目录下所有文件
2.5.2 单个文件复制
2.5.3 递归复制
public static void main(String[] args) {
File file = new File("D:\\33期\\课件");
m1(file);
}
public static void m1(File file) {
// 判断是否是文件
if (file.isFile()) {
// 如果是文件,则打印文件路径
// System.out.println(file.getAbsolutePath());
// 源文件路径
String oldFilePath = file.getAbsolutePath();
// 目标文件路径
String targetFilePath = "E" + oldFilePath.substring(1);
// 判断目标目录是否存在
File targetParentFile = new File(targetFilePath).getParentFile();
if (!targetParentFile.exists()) {
// 不存在就创建
targetParentFile.mkdirs();
}
try (
// 字节输入流
FileInputStream fis = new FileInputStream(oldFilePath);
// 字节输出流
FileOutputStream fos = new FileOutputStream(targetFilePath);
// 字节输入缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
// 字节输出缓冲流
BufferedOutputStream bos = new BufferedOutputStream(fos);) {
// available 可读取的字节个数
// 数组大小并不是越大越好,大小刚刚好最合适
byte[] bytes = new byte[fis.available()];
int temp = 0;
while ((temp = bis.read(bytes)) != -1) {
bos.write(bytes, 0, temp);
bos.flush();
}
System.out.println("复制完成");
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// 如果不是文件,就获取所有子文件,进行遍历
File[] subFiles = file.listFiles();
// 对每一个子文件进行相同的判断操作
for (File subFile : subFiles) {
m1(subFile);
}
}
三、对象流
3.1 概述
3.2 注意
想要实现序列化,必须实现Serializable接口,该接口没有其他方法功能,仅仅是标记可以被序列化而已
否则会出现以下错误
3.3 序列化
3.4 反序列化
3.5 serialVersionUID
Exception in thread “main” java.io.InvalidClassException: day02.User; local class incompatible: stream classdesc serialVersionUID = 2880521591786075964, local class serialVersionUID = -8655810197319643838
3.6 Transient
23552651830)]
3.4 反序列化
[外链图片转存中…(img-ieN7EOSU-1723552651831)]
3.5 serialVersionUID
Exception in thread “main” java.io.InvalidClassException: day02.User; local class incompatible: stream classdesc serialVersionUID = 2880521591786075964, local class serialVersionUID = -8655810197319643838
[外链图片转存中…(img-lQv9O7lv-1723552651831)]