【Java I/O 流】文件字节输入输出流:FileInputStream & FileOutputStream(文件读写案例)

简介: 本篇文章主要讲述“文件字节输入流”和“文件字节输出流”两个类的使用,并列举了一些案例,帮助学习。

在这里插入图片描述

❤️ 个人主页:水滴技术
🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬
🌸 订阅专栏:Java 教程:从入门到精通

大家好,我是水滴~~

本篇文章主要讲述“文件字节输入流”和“文件字节输出流”两个类的使用,并列举了一些案例,帮助学习。

  • 文件字节输入流(FileInputStream)用于读取文件内容。将磁盘中文件的数据,读取到内存中使用。
  • 文件字节输出流(FileOutputStream)用于向文件写入内容。将内存中的数据,写入到磁盘文件中。

在这里插入图片描述

FileInputStream(文件字节输入流)

java.io.FileInputStream 是抽象类 java.io.InputStream 的一个具体实现类,用于读取文件的原始字节流。

构造函数

FileInputStream 类有三个构造方法,构造方法需要指定要读取的文件。如果指定的文件不存在,会抛出 java.io.FileNotFoundException 异常。

FileInputStream(FileDescriptor fdObj)

通过文件描述符 FileDescriptor 创建一个 FileInputStream 实例,表示与一个实际文件的连接。

FileInputStream(File file)

通过文件 File 创建一个 FileInputStream 实例(最终会创建一个新的文件描述符),表示与一个实际文件的连接。

FileInputStream(String name)

通过文件的路径名创建一个 FileInputStream 实例。最终会创建一个 File 对象,然后调用 FileInputStream(File file) 构造方法。

常用方法

int read()

该方法从输入流读取数据的下一个字节。将读取的字节以 int 型返回,如果读取至末尾,则返回值 -1 。

int read(byte b[])

从输入流中读取多个字节,并将它们存储至缓冲区 b 中。读取的字节数最多等于 b 的长度,也可以读取比 b 长度小的字节数。返回值为实际读取的字节数,如果没有可读取的字节,则返回值 -1。

int read(byte b[], int off, int len)

从输入流中读取 len 个字节,并从缓存区 boff 下标处开始存储(即读取的第一个字节存入缓 b[off] 中,下一个字节存入 b[off + 1] 中...)。同样返回值为实际读取的字节数,如果没有可读取的字节,则返回值 -1。

int available()

返回该输入流中可读取的有效字节数。

void close()

关闭该输入流,并释放与之相关的所有系统资源。

读取文件的案例

通过一些案例来演示 FileInputStream 的使用,加深记忆。

案例一:一次读取一个字节

创建一个文件:C:\io\01.txt,文件内容为:abc

代码示例:

public static void read1() throws IOException {
   
   
    // 通过文件路径创建 FileInputStream 实例
    FileInputStream fis = new FileInputStream("c:/io/01.txt");

    // 可读取的字节数
    System.out.println("可读取的字节数: " + fis.available());

    // 读取一个字节
    int read = fis.read();
    System.out.println("可读取的字节数: " + fis.available() + "\t读取内容: " + read);

    // 读取一个字节
    read = fis.read();
    System.out.println("可读取的字节数: " + fis.available() + "\t读取内容: " + read);

    // 读取一个字节
    read = fis.read();
    System.out.println("可读取的字节数: " + fis.available() + "\t读取内容: " + read);

    // 读取一个字节
    read = fis.read();
    System.out.println("可读取的字节数: " + fis.available() + "\t读取内容: " + read);

    // 关闭输入流
    fis.close();
}

输出内容:

可读取的字节数: 3
可读取的字节数: 2  读取内容: 97
可读取的字节数: 1  读取内容: 98
可读取的字节数: 0  读取内容: 99
可读取的字节数: 0  读取内容: -1

通过该案例可以发现:

  • read() 方法读取的字节以 int 型返回。如上例,a的 ASCII 码值为 97b的 ASCII 码值为 98c的 ASCII 码值为 99
  • 读取完最后一个字节,available() 可读取的字节数为0
  • 读取完最后一个字节,再次 read() 读取,返回值为 -1
  • 最后不要完了关闭流。

案例二:通过循环判断可读取字节数,一次读取一个字节

使用案例一中的文件:C:\io\01.txt,文件内容为:abc

代码示例:

public static void read2() throws IOException {
   
   
    // 通过文件路径创建 FileInputStream 实例
    FileInputStream fis = new FileInputStream("c:/io/01.txt");

    // 循环判断可读取字节数
    while (fis.available() > 0) {
   
   
        // 读取一个字节
        int read = fis.read();
        System.out.println("可读取的字节数: " + fis.available() + "\t读取内容: " + read);
    }

    // 关闭输入流
    fis.close();
}

输出内容:

可读取的字节数: 2  读取内容: 97
可读取的字节数: 1  读取内容: 98
可读取的字节数: 0  读取内容: 99

案例三:通过循环判断是否读到末尾,一次读取一个字节

使用案例一中的文件:C:\io\01.txt,文件内容为:abc

代码示例:

public static void read3() throws IOException {
   
   
    // 通过文件路径创建 FileInputStream 实例
    FileInputStream fis = new FileInputStream("c:/io/01.txt");

    int read;
    // 循环读取一个字节,每次判断是否到达末尾
    while ((read = fis.read()) != -1) {
   
   
        System.out.println("可读取的字节数: " + fis.available() + "\t读取内容: " + (char)read);
    }

    // 关闭输入流
    fis.close();
}

输出内容:

可读取的字节数: 2  读取内容: a
可读取的字节数: 1  读取内容: b
可读取的字节数: 0  读取内容: c

案例四:一次读取多个字节

使用案例一中的文件:C:\io\01.txt,文件内容为:abc

代码示例:通过 new String(bytes) 方法将读取的字节数组转为字符串

public static void read4() throws IOException {
   
   
    // 通过文件路径创建 FileInputStream 实例
    FileInputStream fis = new FileInputStream("c:/io/01.txt");
    // 可读取的字节数
    System.out.println("可读取的字节数: " + fis.available());

    // 字节数组,缓存读取的内容
    byte[] bytes = new byte[2];

    // 一次读取多个字节
    int len = fis.read(bytes);
    System.out.println("可读取的字节数: " + fis.available() + "\t读取的字节数: " + len + "\t读取内容: " + new String(bytes));

    // 一次读取多个字节
    len = fis.read(bytes);
    System.out.println("可读取的字节数: " + fis.available() + "\t读取的字节数: " + len + "\t读取内容: " + new String(bytes));

    // 一次读取多个字节
    len = fis.read(bytes);
    System.out.println("可读取的字节数: " + fis.available() + "\t读取的字节数: " + len + "\t读取内容: " + new String(bytes));

    // 关闭输入流
    fis.close();
}

输出内容:

可读取的字节数: 3
可读取的字节数: 1  读取的字节数: 2   读取内容: ab
可读取的字节数: 0  读取的字节数: 1   读取内容: cb
可读取的字节数: 0  读取的字节数: -1  读取内容: cb

通过该案例可以发现:

  • read()方法返回值为读取的内容;而read(bytes)方法返回值为读取的字节数。
  • 字节数组未被填满时,剩余位置会保留原来的值。
  • 通过 new String(bytes) 方法可以将字节数组转为字符串。

案例五:通过循环判断可读取字节数,一次读取多个字节

使用案例一中的文件:C:\io\01.txt,文件内容为:abc

代码示例:

public static void read5() throws IOException {
   
   
    // 通过文件路径创建 FileInputStream 实例
    FileInputStream fis = new FileInputStream("c:/io/01.txt");

    // 字节数组,缓存读取的内容
    byte[] bytes = new byte[2];

    while (fis.available() > 0) {
   
   
        // 一次读取多个字节
        int len = fis.read(bytes);
        System.out.println("可读取的字节数: " + fis.available() + "\t读取的字节数: " + len + "\t读取内容: " + new String(bytes, 0, len));
    }

    // 关闭输入流
    fis.close();
}

输出内容:

可读取的字节数: 1  读取的字节数: 2  读取内容: ab
可读取的字节数: 0  读取的字节数: 1  读取内容: c

通过该案例可以发现:

  • 使用 new String(bytes, 0, len) 方法可以将有效的字节转为字符串,解决了数组未填满的情况。

案例六:通过循环判断是否读到末尾,一次读取多个字节

使用案例一中的文件:C:\io\01.txt,文件内容为:abc

代码示例:

public static void read6() throws IOException {
   
   
    // 通过文件路径创建 FileInputStream 实例
    FileInputStream fis = new FileInputStream("c:/io/01.txt");

    // 字节数组,缓存读取的内容
    byte[] bytes = new byte[2];
    int len;
    // 循环读取一个字节,每次判断是否到达末尾
    while ((len = fis.read(bytes)) != -1) {
   
   
        System.out.println("可读取的字节数: " + fis.available() + "\t读取的字节数: " + len + "\t读取内容: " + new String(bytes, 0, len));
    }

    // 关闭输入流
    fis.close();

}

输出内容:

可读取的字节数: 1  读取的字节数: 2  读取内容: ab
可读取的字节数: 0  读取的字节数: 1  读取内容: c

FileOutputStream(文件字节输出流)

java.io.FileOutputStream 是抽象类 java.io.OutputStream 的一个具体实现类,用于将数据写入到文件的输出流中。某些平台允许一次只能打开一个文件输出流。

构造函数

FileOutputStream 类有五个构造函数,构造函数需要指定要写入的目标文件。如果目标文件所属目录不存在,会抛出 java.io.FileNotFoundException 异常;如果仅是目标文件不存在,会创建一个文件。

FileOutputStream(FileDescriptor fdObj)

通过指定的文件描述符 FileDescriptor 创建一个 FileOutputStream 实例,表示与一个实际文件的连接。

FileOutputStream(File file, boolean append)

通过指定的文件File创建一个FileOutputStream 实例。如果appendtrue,表示从末尾追加,否则会将原数据覆盖。

FileOutputStream(File file)

通过指定的文件 File 创建一个FileOutputStream 实例,默认覆盖文件中原数据。

FileOutputStream(String name, boolean append)

通过文件的路径名创建一个 FileOutputStream 实例。如果appendtrue,表示从末尾追加,否则会将原数据覆盖。

FileOutputStream(String name)

通过文件的路径名创建一个 FileOutputStream 实例,默认覆盖文件中原数据。

常用方法

void write(int b)

向输出流中写入一个字节。该方法是一个抽象方法,要求子类必须实现此方法。

void write(byte b[])

向输出流中写入多个字节。该方法将缓存区 b 中的字节写入到输出流中。

void write(byte b[], int off, int len)

向输出流中写入多个字节,从缓存区 boff 下标处开始写入 len 个字节。

void flush()

刷新该输出流,强制将缓存区中的字节写出去。

void close()

关闭该输出流,并释放与之相关的所有资源。

写入文件的案例

案例一:一次写入一个字节

代码示例:

public static void write1() throws IOException {
   
   
    // 通过文件路径创建 FileOutputStream 实例
    FileOutputStream fos = new FileOutputStream("c:/io/02.txt");

    // 写入一个字节 97=a
    fos.write(97);
    // 写入一个字节 98=b
    fos.write(98);
    // 写入一个字节 99=c
    fos.write(99);

    // 关闭输出流
    fos.close();
}

会创建一个c:/io/02.txt 文件,文件内容为:abc

案例二:一次写入多个字节

代码示例:

public static void write2() throws IOException {
   
   
    // 通过文件路径创建 FileOutputStream 实例
    FileOutputStream fos = new FileOutputStream("c:/io/03.txt");

    String str = "水滴abc";
    byte[] bytes = str.getBytes();
    fos.write(bytes);

    // 关闭输出流
    fos.close();
}

会创建一个c:/io/03.txt 文件,文件内容为:水滴abc

案例三:一次写入多个字节,指定字节数组的偏移量

代码示例:

public static void write3() throws IOException {
   
   
    // 通过文件路径创建 FileOutputStream 实例
    FileOutputStream fos = new FileOutputStream("c:/io/04.txt");

    String str = "水滴abc";
    byte[] bytes = str.getBytes();
    fos.write(bytes, 0, bytes.length - 3);

    // 关闭输出流
    fos.close();
}

会创建一个c:/io/03.txt 文件,文件内容为:水滴


系列文章

相关文章
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
80 9
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
87 2
|
4天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
48 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
25天前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
86 34
|
2月前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
45 3
|
2月前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
2月前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
125 2
|
Java
java中I/O流之字节流和字符流学习总结(下)
java中I/O流之字节流和字符流学习总结(下)
121 0
java中I/O流之字节流和字符流学习总结(下)
|
移动开发 Java 数据库
java中I/O流之字节流和字符流学习总结(上)
java中I/O流之字节流和字符流学习总结(上)
138 0
java中I/O流之字节流和字符流学习总结(上)
|
移动开发 Java
Java I/O学习(附实例和详解)
版权声明:本文为博主原创文章,转载注明出处http://blog.csdn.net/u013142781 目录(?)[+] 一、Java I/O类结构以及流的基本概念 在阅读Java I/O的实例之前我们必须清楚一些概念,我们先看看Java I/O的类结构图: Java I/O主要以流的形式进行读写数据。
2545 0