Java IO:流、File文件、字节流、字符流、序列化与反序列化
目录
一.什么是流
1.流Stream的定义
2.核心特点
(1)单向性
(2)顺序性:
3.分类
(1)按照数据流的方向:
(2)按照处理数据单位:
(3)按照实现功能:
二.File类
1.定义
2.常用构造方法
3.常用判断方法
4.创建方法
5.删除方法
6.获取信息方法
7.目录遍历
三.字节流
1.定义:
2.适用范围
3.方向分类
4.抽象父类与文件子类
5.OutputStream ,InputStream常用方法
6.FileOutputStream ,FileInputStream的常用方法
7.核心常用方法
8.文件写入基础代码实例
文件读取基础示例
文件复制经典案例
四.字符流
1.定义:
2.类别
3.常用方法
(1)Reader类的常用方法
(2)Writer类的常用方法
(3)FileReader常用构造方法
(4)FileWriter常用构造方法
4.字符流写入文本
5.字符流读取文本
五.序列化和反序列化
1.序列化
定义:
作用:
2.反序列化
3.常用方法
(1)ObjectOutputStream(序列化流)
(2)ObjectInputStream(反序列化流)
4.示例
一.什么是流
1.流Stream的定义
内存与存储设备之间传输数据的的管道,使Java程序读写文件,传输数据,不会直接操作文件,都是通过流来完成
2.核心特点
(1)单向性
(2)顺序性:
数据从头到尾依次传输,不能跳着读,跳着写
3.分类
(1)按照数据流的方向:
输入流Input (将存储设备中的内容读入到内存)和 输出流Output(将内存中的内容写入到存储设备)
(2)按照处理数据单位:
字节流InputStream / OutputStream 和 字符流Reader / Writer
(3)按照实现功能:
节点流(低级流:直接跟输入输出对接)和 处理流(高级流:建立在低价流的基础上)
二.File类
1.定义
File类存在Java.io包里,专门表示电脑上的文件/文件夹路径,主要用来获取文件的一些信息,创建,删除,隐藏,遍历文件等
注意:File只操作路劲,读写要用字节流或字符流
2.常用构造方法
| 方法 | 类型 | 描述 |
| public File(String pathname){.....} | 构造方法 | 文件的完整路径 |
| public File(File parent, String child){.....} | 构造方法 | 文件的父路径和子文件路径 |
// 1. 传入文件路径 File f1 = new File("a.txt"); // 2. 父路径+子文件名 File f2 = new File("F:/myfiles","1.txt"); // 3. File对象+文件名 File parent = new File("F:/myfiles"); File f3 = new File(parent,"1.txt");3.常用判断方法
| 方法 | 描述 |
| public boolean exists() | 判断文件/文件夹是否存在 |
| public boolean isFile() | 判断是不是文件 |
| public boolean isDirectory() | 判断是不是文件夹 |
| public boolean canRead() | 是否可读 |
| public boolean canWrite() | 是否可写 |
| public boolean isHidden() | 是否隐藏文件 |
4.创建方法
| 方法 | 描述 |
| public boolean createNewFile()throws IOException{.....} | 创建空文件,成功返回true |
| public boolean mKdir() | 创建单层文件夹,创建目录 |
| public boolean mKdirs() | 创建多层嵌套文件夹 |
5.删除方法
| public boolean delete() | 删除文件/空文件夹,直接彻底删除,不走回收站 |
6.获取信息方法
| 方法 | 描述 |
| getName() | 获取文件名/文件夹名 |
| getPath() | 获取创建时写的路径 |
| getAbsolutePath() | 获取绝对完整路径 |
| length() | 获取文件字节大小,文件夹返回0 |
| lastModified() | 获取最后修改时间 |
7.目录遍历
| 方法 | 描述 |
| list() | 返回目录下所有文件名字符串数组 |
| listFiles() | 返回目录下所有File对象数组,遍历文件首选 |
import java.io.File; import java.io.IOException; public class FileTest { public static void main(String[] args) throws IOException { File file = new File("test.txt"); // 创建文件 if(!file.exists()){ file.createNewFile(); } // 获取信息 System.out.println("文件名:"+file.getName()); System.out.println("绝对路径:"+file.getAbsolutePath()); System.out.println("是否是文件:"+file.isFile()); } }三.字节流
1.定义:
以字节为单位传输数据,最小操作单元 1 字节
2.适用范围
全能型流,文本、图片、视频、压缩包等所有文件都能处理
3.方向分类
输入流:读取文件数据到程序
输出流:把程序数据写入文件
4.抽象父类与文件子类
抽象父类:
InputStream:字节输入流顶层父类
OutputStream:字节输出流顶层父类
常用文件子类:
FileInputStream:读取文件字节数据
FileOutputStream:向文件写入字节数据
5.OutputStream ,InputStream常用方法
| OutputStream方法 | 类型 | 描述 |
| public abstract void write (int a) throws IOException; | 普通方法 | 输入单字节 |
| public void write(byte[] b) throws IOException; | 普通方法 | 输入字节数组 |
| public void write(byte[] b,int of,int len) throws IOException; | 普通方法 | 输入一段字节数组 |
| public void flush() throws IOException; | 普通方法 | 刷新缓冲区 |
| public void close() throws IOException; | 普通方法 | 关闭输出流 |
| InputStream方法 | 类型 | 描述 |
| public abstract int read() throws IOException; | 普通方法 | 从文件中读一个字节,返回 - 1 为结束 |
| public void read(byte[] b) throws IOException; | 普通方法 | 从文件中读多个字节,读满 b 数组,返回值为实际读到的字节数,以 - 1 结束 |
| public void read(byte[] b, int off, int len) throws IOException; | 普通方法 | 从文件中读多个字节,读入 b 中的一段,返回值为实际读到的字节数,以 - 1 为结束 |
| public void close() throws IOException; | 普通方法 | 关闭输入流 |
| public byte[] readAllBytes() throws IOException; | 普通方法(JDK1.9 新增) | 读入输入流全部字节数据 |
| public long transferTo(OutputStream out) throws IOException; | 普通方法(JDK1.9 新增) | 输入流转存到输出流 |
6.FileOutputStream ,FileInputStream的常用方法
| FileOutputStream方法 | 类型 | 描述 |
| public FileOutputStream (File file) throws FileNotFoundException{...} | 构造方法 | 创建文件传输流,File对象指定文件路径 |
| public FileOutputStream (File file,boolean append ) throws FileNotFoundException{...} | 构造方法 | 创建文件传输流,用布尔值指定是否在文件后追加内容 |
| public FileOutputStream (String name) throws FileNotFoundException{...} | 构造方法 | 创建文件传输流,该文件通过文件系统中的路径名name指定 |
| FileInputStream方法 | 类型 | 描述 |
| public FileInputStream(File file) throws FileNotFoundException { … } | 构造方法 | 创建文件输入流,File 对象指定文件路径 |
| public FileInputStream(String name) throws FileNotFoundException { … } | 构造方法 | 创建文件输入流,文件系统中的路径名 name 指定 |
7.核心常用方法
输入流读取方法
read():单次读 1 个字节,返回字节数值,无数据返回 - 1read(byte[] b):批量读取,存入字节数组,返回实际读取长度close():关闭流,释放资源,必须调用
输出流写入方法
write(int b):写入单个字节write(byte[] b):写入整个字节数组write(byte[] b,int off,int len):从指定下标写入指定长度字节close():关闭流
8.文件写入基础代码实例
import java.io.FileOutputStream; import java.io.IOException; public class ByteOutDemo { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("data.txt"); String msg = "字节流测试内容"; byte[] arr = msg.getBytes(); fos.write(arr); fos.close(); } }文件读取基础示例
import java.io.FileInputStream; import java.io.IOException; public class ByteInDemo { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("data.txt"); byte[] buf = new byte[1024]; int len; while((len = fis.read(buf)) != -1){ System.out.print(new String(buf,0,len)); } fis.close(); } }文件复制经典案例
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyFile { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("source.jpg"); FileOutputStream fos = new FileOutputStream("target.jpg"); byte[] buf = new byte[1024]; int len; while((len = fis.read(buf))!=-1){ fos.write(buf,0,len); } fis.close(); fos.close(); } }四.字符流
1.定义:
以1 个字符为单位(英文 / 中文直接处理,不用手动转字节),纯文本文件,不适合图片、视频、压缩包等二进制文件
2.类别
抽象父类
Reader:字符输入流(读文本
Writer:字符输出流(写文本
子类
FileReader:文件字符输入流(读文本文件
FileWriter:文件字符输出流(写文本文件
3.常用方法
(1)Reader类的常用方法
| 方法 | 类型 | 描述 |
|---|---|---|
public abstract int read() throws IOException; | 普通方法 | 读取单个字符,返回字符的 Unicode 值,无数据返回 - 1 |
public int read(char[] cbuf) throws IOException; | 普通方法 | 读取多个字符到字符数组,返回实际读取的字符数,无数据返回 - 1 |
public abstract int read(char[] cbuf, int off, int len) throws IOException; | 普通方法 | 读取指定长度的字符到数组的指定位置,返回实际读取的字符数,无数据返回 - 1 |
public abstract void close() throws IOException; | 普通方法 | 关闭字符输入流,释放资源 |
(2)Writer类的常用方法
| 方法 | 类型 | 描述 |
|---|---|---|
public void write(int c) throws IOException; | 普通方法 | 写入单个字符 |
public void write(char[] cbuf) throws IOException; | 普通方法 | 写入整个字符数组 |
public abstract void write(char[] cbuf, int off, int len) throws IOException; | 普通方法 | 写入字符数组的指定部分 |
public void write(String str) throws IOException; | 普通方法 | 直接写入字符串(字符流的优势,不用转字节) |
public void write(String str, int off, int len) throws IOException; | 普通方法 | 写入字符串的指定部分 |
public abstract void flush() throws IOException; | 普通方法 | 刷新缓冲区,强制把数据写入文件 |
public abstract void close() throws IOException; | 普通方法 | 关闭字符输出流(关闭前会自动刷新) |
(3)FileReader常用构造方法
| 方法 | 类型 | 描述 |
|---|---|---|
public FileReader(String fileName) throws FileNotFoundException; | 构造方法 | 根据文件路径创建字符输入流 |
public FileReader(File file) throws FileNotFoundException; | 构造方法 | 根据 File 对象创建字符输入流 |
(4)FileWriter常用构造方法
| 方法 | 类型 | 描述 |
|---|---|---|
public FileWriter(String fileName) throws IOException; | 构造方法 | 根据文件路径创建字符输出流(默认覆盖原文件) |
public FileWriter(String fileName, boolean append) throws IOException; | 构造方法 | 创建字符输出流,append=true时为追加写入 |
public FileWriter(File file) throws IOException; | 构造方法 | 根据 File 对象创建字符输出流(默认覆盖) |
public FileWriter(File file, boolean append) throws IOException; | 构造方法 | 根据 File 对象创建追加模式的字符输出流 |
4.字符流写入文本
import java.io.FileWriter; import java.io.IOException; public class CharWriteDemo { public static void main(String[] args) throws IOException { // 1. 覆盖模式写入(默认) FileWriter writer = new FileWriter("charTest.txt"); writer.write("第一行:字符流写入的中文内容\n"); writer.write("第二行:直接写字符串,不用转字节!"); writer.close(); // 关闭流,自动刷新缓冲区 // 2. 追加模式写入(append=true) FileWriter appendWriter = new FileWriter("charTest.txt", true); appendWriter.write("\n第三行:这是追加写入的内容"); appendWriter.close(); } }5.字符流读取文本
import java.io.FileReader; import java.io.IOException; public class CharReadDemo { public static void main(String[] args) throws IOException { FileReader reader = new FileReader("charTest.txt"); // 方式1:单个字符读取(效率低,了解即可) /* int ch; while ((ch = reader.read()) != -1) { System.out.print((char) ch); } */ // 方式2:字符数组批量读取(推荐,效率高) char[] buf = new char[1024]; // 缓冲区大小 int len; while ((len = reader.read(buf)) != -1) { System.out.print(new String(buf, 0, len)); } reader.close(); } }五.序列化和反序列化
1.序列化
定义:
把Java对象(内存里的)转换成字节数据(可以存到文件/网络传输)
作用:
保存对象状态,传输对象数据
2.反序列化
定义:
把字节数据(文件/网络来的)还原Java对象(内存里的)
作用:
读取之前保存到对象,接收传输的对象数据
注意:
想要一个类的对象可以被序列化,必须实现java.io.Serializable接口
这是一个标记接口(没有任何方法,不用重写
3.常用方法
(1)ObjectOutputStream(序列化流)
用于把对象写入文件/流中
| 方法 | 类型 | 描述 |
|---|---|---|
public ObjectOutputStream(OutputStream out) throws IOException | 构造方法 | 包装一个字节输出流,创建序列化流 |
public final void writeObject(Object obj) throws IOException | 普通方法 | 序列化对象并写入流中 |
public void flush() throws IOException | 普通方法 | 刷新缓冲区,强制写入数据 |
public void close() throws IOException | 普通方法 | 关闭流,释放资源 |
(2)ObjectInputStream(反序列化流)
用于从文件/流中读取对象
| 方法 | 类型 | 描述 |
|---|---|---|
public ObjectInputStream(InputStream in) throws IOException | 构造方法 | 包装一个字节输入流,创建反序列化流 |
public final Object readObject() throws IOException, ClassNotFoundException | 普通方法 | 读取并反序列化对象 |
public void close() throws IOException | 普通方法 | 关闭流,释放资源 |
4.示例
(1)创建可序列化的类
import java.io.Serializable; // 实现Serializable接口,开启序列化功能 public class Student implements Serializable { // 序列化版本号(规范写法) private static final long serialVersionUID = 1L; // 成员变量(transient修饰的变量不会被序列化) private String name; private int age; private transient String password; // 临时变量,序列化时会被忽略 // 构造方法 public Student(String name, int age, String password) { this.name = name; this.age = age; this.password = password; } // 重写toString,方便打印对象信息 @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", password='" + password + '\'' + '}'; } }(2)序列化和反序列化
import java.io.*; public class SerialDemo { public static void main(String[] args) { // 1. 序列化:把对象写入文件 try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.obj"))) { Student stu = new Student("张三", 20, "123456"); oos.writeObject(stu); System.out.println("序列化成功:对象已保存到 student.obj"); } catch (IOException e) { e.printStackTrace(); } // 2. 反序列化:从文件读取对象 try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student.obj"))) { Student stu = (Student) ois.readObject(); System.out.println("反序列化成功:" + stu); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } }