魔术桌
  • 更新日志
  • 新闻资讯
  • 数据资产
  • 网站导航
  • 订阅推荐
  • 商品推广
  • 日记
  • 摘录
  • 论文
  • 方案
  • 技术
  • 风格
  • 视觉
  • 原材料
  • 加工工艺
  • 元器件
  • 产品设备
  • 设计模式
  • 数据结构
  • 算法设计
  • 软件架构
  • 程序语言
  • 代码类库
  • 操作系统
  • 软件包
  • 健康
  • 环境
  • 社会
  • 道德
  • 法律
  • 经济
  • 政策
  • 更新日志
  • 新闻资讯
  • 数据资产
  • 网站导航
  • 订阅推荐
  • 商品推广
  • 日记
  • 摘录
  • 论文
  • 方案
  • 技术
  • 风格
  • 视觉
  • 原材料
  • 加工工艺
  • 元器件
  • 产品设备
  • 设计模式
  • 数据结构
  • 算法设计
  • 软件架构
  • 程序语言
  • 代码类库
  • 操作系统
  • 软件包
  • 健康
  • 环境
  • 社会
  • 道德
  • 法律
  • 经济
  • 政策
  • Language - Java - Java SE - API - 「java.io」

文章摘要: Java 平台提供的一组输入/输出(I/O)相关的 API。

介绍

简要说明

  • 通过数据流、序列化和文件系统提供系统输入和输出。
  • Java 平台提供的一组输入/输出(I/O)相关的 API。
  • 用于处理数据流、文件操作以及其他与 I/O 相关的任务。
  • 提供了丰富的类和接口,以支持不同类型的 I/O 操作。

主要功能

  • 流操作:提供了字节流(InputStream 和 OutputStream)和字符流(Reader 和 Writer)来处理二进制和文本数据。
  • 文件操作:提供了 File 类来表示文件和目录路径信息,并可以进行创建、删除、重命名等操作。
  • 序列化与反序列化:支持对象的序列化(将对象状态保存到字节流)和反序列化(从字节流恢复对象状态)。
  • 缓冲区操作:提供了缓冲流(BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter)来提高 I/O 操作的效率。
  • 数据操作:提供了 DataInputStream 和 DataOutputStream 用于读写基本数据类型。
  • 对象流操作:提供了 ObjectInputStream 和 ObjectOutputStream 用于对象的序列化和反序列化。
  • 随机访问文件:提供了 RandomAccessFile 类用于随机访问文件内容。

注意事项

  • 资源管理:在使用 I/O 资源时,应该始终注意资源的关闭,以避免资源泄露。Java 7 引入了 try-with-resources 语句来简化资源管理。
  • 异常处理:I/O 操作可能抛出 IOException,因此需要妥善处理这些异常。
  • 性能考虑:使用缓冲流可以提高 I/O 操作的性能,特别是在处理大量数据时。
  • 字符编码:在处理文本数据时,需要特别注意字符编码问题,以避免乱码。

适用场景

  • 文件读写:当需要读取或写入文件时,java.io 提供了丰富的类和方法来支持这些操作。
  • 网络通信:在网络编程中,经常需要使用 java.io 来处理网络数据流。
  • 数据序列化:当需要将对象状态持久化或通过网络传输对象时,可以使用 java.io 的序列化机制。
  • 系统间数据交换:java.io 可以用于不同系统或组件之间的数据交换。
  • 基础数据处理:在处理基本数据类型和字符串时,java.io 提供了方便的 API。

基本概念

  • 流(Stream): 数据的流动,可以是输入流(读取数据)或输出流(写入数据)。
  • 字节流(Byte Stream): 以字节为单位进行读写,适用于所有类型的文件数据。
  • 字符流(Character Stream): 以字符为单位进行读写,适用于文本文件。
  • 过滤器流(Filter Stream): 用于装饰其他流,提供额外的功能,如缓冲、数据压缩、加密等。

主要类和接口

输入流(InputStream 和 Reader)

  • InputStream: 所有输入字节流的超类,提供读取字节的基本方法。
  • Reader: 所有输入字符流的超类,提供读取字符的基本方法。
  • FileInputStream: 用于从文件系统中的文件读取数据。
  • FileReader: 用于从文件系统中的文件读取文本数据。
  • BufferedInputStream: 用于包装另一个输入流,提供缓冲功能,提高读取效率。
  • BufferedReader: 用于包装另一个输入流,提供缓冲功能,提高文本读取效率。

输出流(OutputStream 和 Writer)

  • OutputStream: 所有输出字节流的超类,提供写入字节的基本方法。
  • Writer: 所有输出字符流的超类,提供写入字符的基本方法。
  • FileOutputStream: 用于向文件系统中的文件写入数据。
  • FileWriter: 用于向文件系统中的文件写入文本数据。
  • BufferedOutputStream: 用于包装另一个输出流,提供缓冲功能,提高写入效率。
  • BufferedWriter: 用于包装另一个输出流,提供缓冲功能,提高文本写入效率。

其他重要类

  • File: 提供文件和目录路径名的操作。
  • RandomAccessFile: 支持随机访问文件的读写操作。
  • ObjectInputStream/ObjectOutputStream: 用于对象的序列化和反序列化。
  • InputStreamReader/OutputStreamWriter: 用于在字节流和字符流之间转换。

学习总结

文件操作

  • 文件读写: 学习如何使用 FileInputStream/FileOutputStream 和 FileReader/FileWriter 进行文件的基本读写操作。
  • 随机访问文件: 了解 RandomAccessFile 的使用,它可以跳转到文件的任意位置进行读写。

流操作

  • 流类型: 区分字节流和字符流,了解它们的使用场景。
  • 缓冲流: 学习使用 BufferedInputStream/BufferedReader 和 BufferedOutputStream/BufferedWriter 来提高 I/O 操作的效率。
  • 过滤器流: 掌握如何使用过滤器流(如 DataInputStream/DataOutputStream)来处理不同类型的数据。

序列化

  • 对象序列化: 学习如何使用 ObjectOutputStream 和 ObjectInputStream 来序列化和反序列化对象。

资源管理

  • 关闭流: 确保在不再需要时关闭流,释放系统资源,可以使用 try-with-resources 语句来自动关闭资源。
  • 异常处理: 学习如何处理 IOException 和其他相关异常。

实践建议

  • 使用缓冲: 总是使用缓冲流来包装原始流,以提高性能。
  • 异常处理: 在 I/O 操作中总是包含异常处理逻辑。
  • 资源管理: 使用 try-with-resources 语句来管理资源,避免资源泄露。
  • 文件路径: 注意操作系统之间的文件路径差异。
  • 编码问题: 在处理文本文件时,注意字符编码和解码的问题。

java.io.File

相关信息

  • File对象用于代表硬盘中的一个文件或文件夹。
  • File对象只能对文件本身进行操作,不能读写文件里面存储的数据进行操作。
  • File对象能接收一个不存在的文件或文件夹。
  • 支持“绝对路径、相对路径”的文件路径。
  • 类库路径:java.io.File

实例化File对象

方法说明
new File(String <文件路径>)根据文件路径创建文件对象
new File(String <父级路径>, String <子路径>)根据父级路径和子路径名称创建文件对象
new File(File <父级路径>, String <子路径>)根据父级路径对应文件对象和子路径名称

创建

方法说明
<File>.createNewFile()创建文件,若创建成功则返回true
<File>.mkdir()创建文件夹,只能创建一级文件夹,若创建成功则返回true
<File>.mkdirs()创建文件夹,可以创建多层级文件夹,若创建成功则返回true

删除

方法说明
<File>.delete()删除文件或空目录,若删除成功则返回true

修改

方法说明
<File>.renameTo()修改文件名称

查询

方法说明
<File>.exists()判断文件是否存在,若存在则返回true
<File>.isFile()判断文件是否是文件,若是文件则返回true
<File>.isDirectory()判断文件是否是文件夹,若是文件夹则返回true
<File>.getName()获取文件的名称(包含后缀)
<File>.length()获取文件的大小,返回字节个数
<File>.lastModified()获取文件的最后修改时间
<File>.getPath()获取创建文件时使用的路径
<File>.getAbsolutePath()获取文件的绝对路径
<File>.getParent()获取文件所在的父级目录
<File>.list()获取当前目录下所有的“一级文件和文件夹的名称”,返回String[]
<File>.listFiles()获取当前目录下所有的“一级文件和文件夹的对象”,返回File[]
  • <File>.canWrite():是否可写
  • <File>.isFile():是否隐藏

案例

分析:

  • 输入文件夹,作为查找范围
  • 遍历全部一级文件对象,判断是否是文件
  • 若是文件,判断是否是自己想要的文件
  • 若是文件夹,则获取该文件夹下全部一级文件,重复上述过程

代码

import java.io.File;
import java.util.ArrayList;

public class Main {
    public static void main(String[] ages) {
        // 创建存放查找结果的文件列表
        ArrayList<String> fileList = new ArrayList<>();

        // 调用方法
        // - 传入查找目录范围(File对象)
        // - 查找的目标文件名
        // - 保存查找到的文件列表
        searchFile(new File("/home/magictable/Projec/"), "Main.java", fileList);

        // 判断文件列表中的最新数据是否为0
        if (fileList.size() == 0) {
            System.out.println("未找到目标文件");
        }
        // 输出文件列表中存储的最新数据
        for (int i=0; i < fileList.size(); i++) {
            // 格式化输出结果
            System.out.println("结果"+ (i+1) + ":" + fileList.get(i));
        }

    }

    /**
     * 搜索指定目录范围下的目标文件
     * @param dir 查找的目录范围(File文件)
     * @param fileName 查找的目标文件名
     * @param fileList 保存查找到的文件列表
     */
    public static void searchFile(File dir, String fileName, ArrayList<String> fileList) {
        // 判断输入的`dir`文件夹:
        // - 是否不存在
        // - 是否是一个文件
        // - 是否是空目录
        if (!dir.exists() || dir.isFile() || dir == null) {
            return;
        }

        // 获取`dir`目录下的全部一级文件对象
        File[] fileArray = dir.listFiles();
        // 判断文件夹大小是否为“0字节”(用于判断是否拥有该文件夹的权限)
        // 是否是空的“文件夹”
        if (fileArray.length > 0  && fileArray != null) {
            // 获取该目录下的全部一级文件对象
            for (File f : fileArray) {
                // 判断文件是否是文件
                if (f.isFile()) {
                    // 判断文件是否是我们要找的
                    if (f.getName().equals(fileName)) {
                        // 将当前文件对象的绝对路径保存到文件列表中
                        fileList.add(f.getAbsolutePath());
                    }
                }
                else {   // 当前文件是一个文件夹
                    // 调用该方法进行重复查找过程,递归算法
                    searchFile(f, fileName, fileList);
                }
            }
        }

    }


}

编码和解码

  • 需要写异常处理。
  • 编码与解码使用的字符集必须一致,才不会出现乱码。

编码

方法说明
<String>.getBytes()使用平台的默认字符集将该String对象编码为一些列字节,返回byte[]
<String>.getBytes(String charsetName)使用指定的字符集将该String对象编码为一些列字节,返回byte[]

解码

方法说明
new String(byte[] bytes)通过使用平台默认字符集解码指定的字节数组,返回新的String
new String(byte[] bytes, String charsetName)通过指定的字符集解码指定的字节数组,返回新的String

IO流基础知识

  • I是Input,输入流,负责把数据读取到内存中。
  • O是Output,输出流,负责把数据写入到(硬盘/网络)中。
  • 内存与存储设备之间传输数据的通道。
  • 用于读写数据。

框架图Java8-API-IO-框架图

IO流的分类

按方向

  • 输入流:将“存储设备/网络”中的内容读入到“内存/本地”中。
  • 输出流:将“内存/本地”中的内容写入到“存储设备/网络”中。

按单位

  • 字节流:以字节为单位,适合读写所有类型的文件。
  • 字符流:以字符为单位,只适合读写文本类型的文件。

按功能

  • 节点流:具有实际传输数据的读写功能,基础流(字节流、字符流)。
  • 过滤流:在节点流的基础之上增强功能,高级流(缓存流、转换流、打印流、数据流、序列化流)。

字节输入流

  • 以内存为基准,将磁盘上的数据以“字节”的形式“读取输入”到内存中。

  • 使用完后需要关闭流。

  • 包路径:java.io.FileInputStream

构造方法

方法说明
new FileInputStream(File file)将File文件对象作为参数进行传输
new FileInputStream(String name)将文件路径作为参数进行传输
new FileInputStream(FileDescriptor fdObj)

相关方法

方法说明
<FileInputStream>.read()从输入流中读取一个字节的数据,返回int,当没有数据时返回-1
<FileInputStream>.read(byte[] b)从输入流中读取b个字节的长度,返回int,当没有数据时返回-1
<FileInputStream>.available()将当前字节输入流对应的文件对象字节数据装到一个字节数组返回

案例

  • 设定固定大小的缓存区,进行多字节批量读取数据。
  • 缺点:读取性能差,频繁与硬盘交互,无法解决乱码问题。
try {
    // 实例化File对象,添加要操作的文件
    File file = new File("/home/abc.text");

    // 实例化字节输入流对象,传入需要读取的File文件对象
 FileInputStream inputFile = new FileInputStream(file);      
 
    // 类似缓存区,一批次能读取多少字节
 byte[] byteData = new byte[3];
    // 记录当前批次读取了多少字节
 int len;
 while ((len = inputFile.read(byteData)) != -1) {
        // 读取的内容是根据data读取多少字节,就输出到多少字节。
        // 该步骤是正在“解码”操作,即将二进制文件转换为字符串数据
        String fileData = new String(byteData, 0, len);
        // 在控制台输出显示
        String.out.print(fileData);
 }
 // 释放输出流对象
 inputFile.close();

} catch (IOException e) {
 System.out.println("文件操作报错:" + e.getMessage());
}

字节输出流

  • 以内存为基准,将内存上的数据以“字节”的形式“写入输出”到磁盘中。

  • 使用完后需要关闭流。

  • 包路径:java.io.FileOutputStream

构造方法

方法说明
new FileOutputStream(File file)(覆盖)创建字节输入流管道与源文件对象接通
new FileOutputStream(String filepath)(覆盖)创建字节输入流管道与源文件路径接通
new FileOutputStream(File file, boolean append)(追加)创建字节输入流管道与源文件对象接通,可追加数据
new FileOutputStream(String filepath, boolean append)(追加)创建字节输入流管道与源文件对象接通,可追加数据

相关方法

  • 提示:写入数据若文件不存在则自动创建。
方法说明
<FileOutputStream>.write(int a)写入一个字节到文件中
<FileOutputStream>.write(byte[] buffer)写入一个字节数组到文件中
<FileOutputStream>.write(byte[] buffer, int pos, int len)写入一个字节数组的一部分到文件中
<FileOutputStream>.flush()刷新,将缓冲区中的内容写入到文件中。
<FileOutputStream>.close()释放流,包含了刷新

案例

try {
    // 实例化File对象,添加要操作的文件
    File file = new File("/home/abc.text");

    // 实例化字节输出流对象,传入需要写入的File文件对象
 FileOutputStream outputFile = new FileOutputStream(file);
 
    // 需要写入文件的数据
    String data = "你好,世界。";

    // 将数据进行“编码”操作,即将字符串数据转换为二进制文件
    byte[] byteData = data.getBytes();

    // 将编码后的数据,通过字节输出流对象,写入到文件
    outputFile.write(byteData);

    // 释放输出流对象
    outputFile.close();

} catch (IOException e) {
 System.out.println("文件复制失败:" + e.getMessage());
}

字符输入流

  • 以内存为基准,可以吧文件中的数据以“字符”的形式“读取输入”到内存中。

  • 使用完后需要关闭流。

  • 包路径:java.io.FileReader

构造方法

方法说明
new FileReader(File file)创建字符输入流管道与源文件接通
new FileReader(String pathname)创建字符输入流管道与源文件接通

相关方法

方法说明
<FileReader>.read()每次读取一个字符返回,若没有数据可读时返回-1
<FileReader>.read(char[] buffer)每次用一个字符数组去读取数据,返回字符数组读取了多少字节,若没有数据可读时返回-1

案例

// 实例化File对象,添加要操作的文件
File file = new File("/home/file.text");

try (
        // 实例化字符输入流,添加要读取的File对象
        FileReader readerFile = new FileReader(file);
) {

    // 创建临时存储空间,存储读取出的字符
    char[] charArray = new char[1024];
    // 记住当批次读取了多少字符
    int len;
    while ((len=readerFile.read(charArray)) != -1) {
        // 将字符列表“解码”成字符串
        String data = new String(charArray, 0, len);
        // 将结果输出到控制台
        System.out.print(data);
    }

} catch (IOException e) {
 System.out.println("文件复制失败:" + e.getMessage());
}

字符输出流

  • 以内存为基准,把内存中的数据以“字符”的形式“写入输出”到文件中。
  • 使用完后需要关闭流。
  • 包路径:java.io.FileWriter

构造方法

方法说明
new FileWriter(File file)(覆盖)创建字节输出流管道与源文件对象接通
new FileWriter(String filepath)(覆盖)创建字节输出流管道与源文件路径接通
new FileWriter(File file, boolean append)(追加)创建字节输出流管道与源文件对象接通,可追加数据
new FileWriter(String filepath, boolean append)(追加)创建字节输出流管道与源文件路径接通,可追加数据

相关方法

方法说明
<FileWriter>.write(int a)写入一个字符
<FileWriter>.write(String str)写入一个字符串
<FileWriter>.write(String str, int off, int len)写入一个字符串的一部分
<FileWriter>.write(char[] cbuf)写入一个字符数组
<FileWriter>.write(char[] cbuf, int off, int len)写入字符数组的一部分
<FileWriter>.flush()刷新,将缓冲区中的内容写入到文件中。
<FileWriter>.close()释放流,包含了刷新

案例

// 实例化File对象,添加要操作的文件
File file = new File("/home/file.text");

try (
        // 实例化字符输出流对象,传入需要写入的File文件对象
        FileWriter fileWriter = new FileWriter(file);
) {
    
    // 需要写入文件的数据
    String data = "你好,世界。";

    // 将数据通过字符输出流对象,写入到File文件
    fileWriter.write(data);

} catch (IOException e) {
 System.out.println("文件写入失败:" + e.getMessage());
}

缓冲流

  • 添加缓冲流,提高原始数据流读写数据的性能,减少与硬盘交互的次数。
  • 缓冲流类似添加“字符数组”,分批次读取数据。

类别

  • BufferedInputStream:缓冲字节输入流
  • BufferedOotputStream:缓冲字节输出流
  • BufferedReader:缓冲字符输入流
  • BufferedWriter:缓冲字符输出流

提示

  • 缓冲流需要传入输入流或输出流,因此需要先创建原始数据流。
  • 缓冲流包装原始数据流。

构造方法

方法说明
new BufferedInputStream(InputStream is)(缓冲字节输入流)默认8192byte缓冲区大小
new BufferedInputStream(InputStream is, int size)(缓冲字节输入流)指定缓冲区大小
new BufferedOotputStream(OutputStream os)(缓冲字节输出流)默认8192byte缓冲区大小
new BufferedOotputStream(OutputStream os, int size)(缓冲字节输出流)指定缓冲区大小
new BufferedReader(Reader fr)(缓冲字符输入流)默认8192byte缓冲区大小
new BufferedReader(Reader fr, int sz)(缓冲字符输入流)指定缓冲区大小
new BufferedWriter(Writer fw)(缓冲字符输出流)默认8192byte缓冲区大小
new BufferedWriter(Writer fw, int sz)(缓冲字符输出流)指定缓冲区大小

相关方法

方法说明
<BufferedReader>.readLine()缓冲字符输入流,读取一行数据,返回String,没有数据时返回null
<BufferedWriter>.newLine()缓冲字符输出流,换行,没有返回值

案例 - 字节流操作

import java.io.IOException;  // IO异常处理类
import java.io.File;         // File文件对象
import java.io.FileInputStream;   // 文本字节输入流
import java.io.FileOutputStream;  // 文本字节输出流
import java.io.BufferedInputStream;   // 文本字节缓冲输入流
import java.io.BufferedOutputStream;  // 文本字节缓冲输出流


public class Main {
    public static void main(String[] ages) {
        // 实例化File对象,添加要读取的文件
        File file = new File("/home/file.text");
        // 实例化File对象,添加要复制写入的文件
        File fileCopy = new File("/home/fileCopy.text");

        try (
                // 实例化字节输入流对象,添加要读取的File对象
                FileInputStream is = new FileInputStream(file);
                // 实例化字节缓冲输入流对象,包装原始字节输入流,即添加缓冲区
                BufferedInputStream bis = new BufferedInputStream(is);

                // 实例化字节输出流对象,添加要写入的File对象
                FileOutputStream of = new FileOutputStream(fileCopy);
                // 实例化字节缓冲输出流对象,包装原始字节输出流,即添加缓冲区
                BufferedOutputStream bos = new BufferedOutputStream(of);
        ) {
            // 创建临时存储空间,存储读取出的字节
            byte[] byteData = new byte[1024];
            // 记录当前批次存储了多少字节
            int len;
            // 循环与硬盘交互
            while ((len = bis.read(byteData)) != -1) {
                // 读取的内容是根据data读取多少字节,就输出到多少字节。
                // 将当批次获得的字节数据,通过字节缓冲输出流,写入到另一个File文件
                bos.write(byteData, 0, len);
            }
        } catch (IOException e) {
            System.out.println("文件复制失败:" + e.getMessage());
        }

    }


}

案例 - 字符流操作

import java.io.IOException;  // IO异常处理类
import java.io.File;         // File文件对象
import java.io.FileReader;   // 文本字符输入流
import java.io.FileWriter;   // 文本字符输出流
import java.io.BufferedReader;   // 文本字符缓冲输入流
import java.io.BufferedWriter;   // 文本字符缓冲输出流


public class Main {
    public static void main(String[] ages) {
        // 实例化File对象,添加需要复制的源文件
        File file = new File("/home/file.text");
        // 实例化File对象,添加需要复制的新文件
        File fileCopy = new File("/home/fileCopy.text");

        try (
                // 实例化字符输入流,添加要读取的File对象
                FileReader fr = new FileReader(file);
                // 实例化字符缓冲输入流,包装原始字符输入流,即添加缓冲区
                BufferedReader br = new BufferedReader(fr);

                // 实例化字符输出流,添加要写入的File对象
                FileWriter fw = new FileWriter(fileCopy);
                // 实例化字符缓冲输出流,包装原始字符输出流,即添加缓冲区
                BufferedWriter bw = new BufferedWriter(fw);
        ) {
            // 创建临时存储空间,存储读取出的字符
            char[] charArray = new char[1024];
            // 记录当前批次存储了多少字符
            int len;
            // 循环与硬盘交互
            while ((len = br.read(charArray)) != -1) {
                // 将当批次获得的字符数据,通过字节缓冲输出流,写入到另一个File文件
                bw.write(charArray, 0, len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


}

转换流

  • 若代码编码和被读取的文本文件的编码不一致,则使用字符流读取文本文件时就会出现乱码。
  • 解决不同编码时,字符流读取文本内容乱码的问题。
  • 解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转换成字符输入流,这样字符输入流中的字符就不会乱码。

类别

  • InputStreamReader字符输入转换流:控制输入读取的文件用什么字符集解码。
  • OutputStreamWrite字符输出转换流:控制输出写入的文件用什么字符集编码。

构造方法

方法说明
new InputStreamReader(InputStream is)(字符输入转换流)把原始的字节输入流,按照代码默认编码转换成字符输入流(与直接使用FileReader的效果一样)
new InputStreamReader(InputStream is, String charset)(字符输入转换流)将原始字节输入流,按照指定字符集编码转成字符输入流
new OutputStreamWrite(OutputStream is)(字符输出转换流)将原始字节数据流,按照文件默认编码转换成字符输出流
new OutputStreamWrite(OutputStream is, String charset)(字符输出转换流)将原始字节数据流,按照指定编码转换成字符输出流

打印流

  • PrintStream:字节打印流
  • PrintWriter:字符打印流

构造方法

字节打印流方法说明
new PrintStream(OutputStream fos)打印流直接通向字节输出流对象
new PrintStream(File file)打印流直接通向File文件对象
new PrintStream(String fileName)打印流直接通向文件路径
new PrintStream(String fileName, Charset charset)指定写入的字符编码
new PrintStream(OutputStream out, boolean autoFlush)指定字节输出流,是否自动刷新
new PrintStream(OutputStream out, boolean autoFlush, String encoding)指定字节输出流,是否自动刷新,字符编码
字符打印流方法说明
new PrintWriter(OutputStream fos)打印流直接通向字符输出流对象
new PrintWriter(File file)打印流直接通向File文件对象
new PrintWriter(String fileName)打印流直接通向文件路径
new PrintWriter(String fileName, Charset charset)指定写入的字符编码
new PrintWriter(OutputStream out, boolean autoFlush)指定字符输出流,是否自动刷新
new PrintWriter(OutputStream out, boolean autoFlush, String encoding)指定字符输出流,是否自动刷新,字符编码

相关方法

字节打印流方法说明
<PrintStream>.println(<任意数据>)打印任意数据,有换行
<PrintStream>.print(<任意数据>)打印任意数据,不会换行
<PrintStream>.write(<数据>)可以支持写字节数据
字符打印流方法说明
<PrintWriter>.println(<任意数据>)打印任意数据,有换行
<PrintWriter>.print(<任意数据>)打印任意数据,不会换行
<PrintWriter>.write(<数据>)可以支持写字节数据

数据流

  • 允许把数据和其类型一并写出去。

类别

  • DataInputStream:输入数据流
  • DataOutputStream:输出数据流

构造方法

输入数据流方法说明
new DataInputStream(OutputStream out)创建新数据输出流包基础的字节输入流
输出数据流方法说明
new DataOutputStream(OutputStream out)创建新数据输出流包基础的字节输出流

相关方法

输入数据流方法说明
<DataInputStream>.readerByte()将byte类型数据写入基础的字节输出流
<DataInputStream>.readerInt()将int类型数据写入基础的字节输出流
<DataInputStream>.readerDouble()将double类型数据写入基础的字节输出流
<DataInputStream>.readerUTF()将字符串数据以UTF-8编码成字节写入基础的字节输出流
输出数据流方法说明
<DataOutputStream>.writeByte(int v)将byte类型数据写入基础的字节输出流
<DataOutputStream>.writeInt(int v)将int类型数据写入基础的字节输出流
<DataOutputStream>.writeDouble(Double v)将double类型数据写入基础的字节输出流
<DataOutputStream>.writeUTF(String str)将字符串数据以UTF-8编码成字节写入基础的字节输出流

序列化流

类别

  • ObjectInputStream:(对象字节输入流)对象反序列化,把文件里的java对象读出来。
  • ObjectOutputStream:(对象字节输出流)对象序列化,把java对象写入到文件中去。

提示:

  • 对象如果需要参与序列化,则必须让该对象的类实现序列化接口java.io.Serializable,用于表示一个标记,通过获取对象是否有该方法来判断对象是否运行被序列化。

构造方法

方法说明
new ObjectInputStream(OutputStream fis)创建对象字符输入流,包装基础的字节输入流
new ObjectOutputStream(OutputStream fos)创建对象字符输出流,包装基础的字节输出流

相关方法

方法说明
<ObjectOutputStream>.readObject()将对象输入读取出来,返回Object
<ObjectOutputStream>.writeObject(object o)将对象输出写入到文件

案例 - 对象序列化

import java.io.*;

public class Main {
    public static void main(String[] ages) {

        // 实例化File对象
        File file = new File("/home/file.text");

        try (
                // 实例化文件字节输出流,添加需要写入数据的File对象
                FileOutputStream fos = new FileOutputStream(file);
                // 实例化对象字节输出流,添加文件字节输出流
                ObjectOutputStream oos = new ObjectOutputStream(fos);
        ) {
            // 创建对象,该对象的类必须继承`Serializable`接口
            User user = User("姓名", 18);
            // 通过对象通过对象字节输出流,将对象写入文件
            oos.writeObject(user);

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


}

案例 - 对象反序列化

import java.io.*;

public class Main {
    public static void main(String[] ages) {

        // 实例化File对象
        File file = new File("/home/file.text");

        try (
                // 实例化文件字节输入流,添加需要读取数据的File对象
                FileInputStream fos = new FileInputStream(file);
                // 实例化对象字节输入流,添加文件字节输入流
                ObjectIntputStream oos = new ObjectIntputStream(fos);
        ) {
            // 通过对象通过对象字节输出流,将对象读取出来
            // (重点)获得将对象文件后,需要手动强转成User对象数据类型
            User user = (User)oos.writeObject(user);

        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


}

IO流的资源释放操作

try-catch-finally

案例

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;


public class Main {
    public static void main(String[] ages) {
        // 实例化File对象,添加要读取的文件
        File file = new File("/home/file.text");
        // 实例化File对象,添加要复制写入的文件
        File fileCopy = new File("/home/fileCopy.text");

        // 实例化字节输入流对象
        InputStream inputFile = null;
        // 实例化字节输出流对象
        OutputStream outputFile = null;

        try {
            // 传入需要读取的File文件对象
            inputFile = new FileInputStream(file);
            // 传入需要写入的File文件对象
            outputFile = new FileOutputStream(fileCopy);

            // 类似缓存区,一批次能读取多少字节
            byte[] byteData = new byte[3];
            // 记录当前批次读取了多少字节
            int len;
            while ((len = inputFile.read(byteData)) != -1) {
                // 读取的内容是根据data读取多少字节,就输出到多少字节。
                // 将读取到的字节数据,通过字节输出流对象,写入到文件
                outputFile.write(byteData, 0, len);
            }

        } catch (IOException e) {
            System.out.println("文件复制失败:" + e.getMessage());

        } finally {
            // 释放输出流对象资源
            try {
                // 判断输出流对象是否已经关闭
                if (outputFile != null) {
                    // 释放输出流对象
                    outputFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 释放输入流对象资源
            try {
                // 判断输入流对象是否已经关闭
                if (inputFile != null) {
                    // 释放输出流对象
                    inputFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}

try-with-resource

案例

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;


public class Main {
    public static void main(String[] ages) {
        // 实例化File对象,添加要读取的文件
        File file = new File("/home/file.text");
        // 实例化File对象,添加要复制写入的文件
        File fileCopy = new File("/home/fileCopy.text");

        try (
                // 实例化字节输入流对象,传入需要读取的File文件对象
                InputStream inputFile = new FileInputStream(file);
                // 实例化字节输出流对象,传入需要写入的File文件对象
                OutputStream outputFile = new FileOutputStream(fileCopy);
        ) {
            
            // 类似缓存区,一批次能读取多少字节
            byte[] byteData = new byte[3];
            // 记录当前批次读取了多少字节
            int len;
            while ((len = inputFile.read(byteData)) != -1) {
                // 读取的内容是根据data读取多少字节,就输出到多少字节。
                // 将读取到的字节数据,通过字节输出流对象,写入到文件
                outputFile.write(byteData, 0, len);
            }

        } catch (IOException e) {
            System.out.println("文件复制失败:" + e.getMessage());
        }

    }


}
更新时间: 2025/11/16 17:17