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.常用方法1Reader类的常用方法2Writer类的常用方法3FileReader常用构造方法4FileWriter常用构造方法4.字符流写入文本5.字符流读取文本五.序列化和反序列化1.序列化定义作用2.反序列化3.常用方法1ObjectOutputStream序列化流2ObjectInputStream反序列化流4.示例一.什么是流1.流Stream的定义内存与存储设备之间传输数据的的管道使Java程序读写文件传输数据不会直接操作文件都是通过流来完成2.核心特点1单向性2顺序性数据从头到尾依次传输不能跳着读跳着写3.分类1按照数据流的方向输入流Input 将存储设备中的内容读入到内存和 输出流Output将内存中的内容写入到存储设备2按照处理数据单位字节流InputStream / OutputStream 和 字符流Reader / Writer3按照实现功能节点流低级流直接跟输入输出对接和 处理流高级流建立在低价流的基础上二.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{.....}创建空文件成功返回truepublic boolean mKdir()创建单层文件夹,创建目录public boolean mKdirs()创建多层嵌套文件夹5.删除方法public boolean delete()删除文件/空文件夹直接彻底删除不走回收站6.获取信息方法方法描述getName()获取文件名/文件夹名getPath()获取创建时写的路径getAbsolutePath()获取绝对完整路径length()获取文件字节大小文件夹返回0lastModified()获取最后修改时间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.常用方法1Reader类的常用方法方法类型描述public abstract int read() throws IOException;普通方法读取单个字符返回字符的 Unicode 值无数据返回 - 1public int read(char[] cbuf) throws IOException;普通方法读取多个字符到字符数组返回实际读取的字符数无数据返回 - 1public abstract int read(char[] cbuf, int off, int len) throws IOException;普通方法读取指定长度的字符到数组的指定位置返回实际读取的字符数无数据返回 - 1public abstract void close() throws IOException;普通方法关闭字符输入流释放资源2Writer类的常用方法方法类型描述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;普通方法关闭字符输出流关闭前会自动刷新3FileReader常用构造方法方法类型描述public FileReader(String fileName) throws FileNotFoundException;构造方法根据文件路径创建字符输入流public FileReader(File file) throws FileNotFoundException;构造方法根据 File 对象创建字符输入流4FileWriter常用构造方法方法类型描述public FileWriter(String fileName) throws IOException;构造方法根据文件路径创建字符输出流默认覆盖原文件public FileWriter(String fileName, boolean append) throws IOException;构造方法创建字符输出流appendtrue时为追加写入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. 追加模式写入appendtrue 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.常用方法1ObjectOutputStream序列化流用于把对象写入文件/流中方法类型描述public ObjectOutputStream(OutputStream out) throws IOException构造方法包装一个字节输出流创建序列化流public final void writeObject(Object obj) throws IOException普通方法序列化对象并写入流中public void flush() throws IOException普通方法刷新缓冲区强制写入数据public void close() throws IOException普通方法关闭流释放资源2ObjectInputStream反序列化流用于从文件/流中读取对象方法类型描述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(); } } }