首页...输入输出流的使用——面向对象程序设计中的文件与IO操作
面向对象程序设计第八章 文件与输入输出流/第二节 输入输出流的使用

输入输出流的使用——面向对象程序设计中的文件与IO操作

2026-03-24

第八章 文件与输入输出流

第二节 输入输出流的使用

概述

输入输出流(Input/Output Streams)是面向对象程序设计中进行数据交换的基础机制,尤其是在文件处理、网络通信和设备交互中扮演重要角色。本节重点讲解输入输出流的基本概念、工作原理、使用方法及常见技巧。通过系统学习,考生能够掌握Java语言中输入输出流的创建、读写操作、缓冲机制、异常处理及流的关闭规范,进而能够熟练进行文件读写以及数据流转换操作。

学习目标包括:

  • 理解输入输出流的基本概念和分类
  • 掌握常用输入输出流类的使用方法
  • 能够正确处理文件的读写操作
  • 熟悉缓冲流的优势及使用方式
  • 了解流的异常处理及关闭规范
  • 通过典型实例巩固理论知识

核心概念

  1. 输入流(InputStream):用于读取数据的字节流,提供从数据源(如文件、内存、网络)读取字节的能力。

  2. 输出流(OutputStream):用于写出数据的字节流,负责将数据写入目标(如文件、内存、网络)。

  3. 字符流(Reader/Writer):以字符为单位进行读写的流,处理文本数据,支持字符编码转换。

  4. 缓冲流(BufferedInputStream/BufferedOutputStream/BufferedReader/BufferedWriter):对基本流进行封装,使用缓冲区提升读写效率。

  5. 字节流与字符流区别:字节流以字节为单位操作,适合处理所有类型数据;字符流以字符为单位,适合文本文件处理。

  6. 流的链式操作:通过多个流的包装,组合实现复杂功能,如缓冲、数据转换等。

  7. 异常处理:IO操作易产生异常,必须通过try-catch-finally或try-with-resources进行安全处理。

  8. 流的关闭:使用完流必须关闭释放资源,避免内存泄漏和文件锁定。


原理分析

输入输出流的核心原理基于字节和字符的顺序读取与写入,所有流均围绕“数据从源头流入程序”或“数据从程序流向目标”的方向构建。流是单向的,数据一次只能沿一个方向流动。

字节流直接处理8位字节,适合所有文件类型(文本、图片、音频等)。

字符流在字节流基础上,结合字符编码表(如UTF-8、GBK),将字节解码为字符,方便文本数据处理。字符流继承自Reader和Writer类。

缓冲流的设计原理是减少物理设备的访问次数,通过内存中的缓冲区批量读写数据,提升效率。比如,BufferedInputStream在读取时会先将一大块数据读入缓冲区,后续读取直接从缓冲区返回,减少磁盘访问。

流的链式操作体现面向对象设计的装饰模式,通过组合多个流对象强化功能,如用BufferedReader包装FileReader,实现带缓冲的字符读取。

流的关闭机制确保数据完整写入磁盘,释放系统资源,是流操作的必备步骤。Java 7引入的try-with-resources语法自动管理流资源,简化编码。


详细内容

1. 输入输出流的分类与基本用法

Java中流分为字节流和字符流两大类,分别对应不同的类层级:

  • 字节输入流基类:InputStream
  • 字节输出流基类:OutputStream
  • 字符输入流基类:Reader
  • 字符输出流基类:Writer

常用的文件字节流类有:FileInputStream、FileOutputStream;
常用的字符流类有:FileReader、FileWriter。

文件读取示例(字节流)

FileInputStream fis = new FileInputStream("data.txt");
int b;
while ((b = fis.read()) != -1) {
    System.out.print((char) b);
}
fis.close();

文件写入示例(字符流)

FileWriter fw = new FileWriter("output.txt");
fw.write("Hello, World!\n");
fw.close();

2. 缓冲流的使用及优势

缓冲流通过内部缓冲区减少物理读写次数,提升性能。常用缓冲流类有:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。

缓冲字符流读取示例

BufferedReader br = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}
br.close();

缓冲流常用于大文件读写,特别是需要按行读取文本文件时,readLine()方法极为方便。

3. 流的异常处理与关闭规范

IO操作易发生FileNotFoundException、IOException等异常,必须妥善处理。推荐使用try-with-resources结构,自动关闭流,代码简洁且安全。

示例:

try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

若不使用try-with-resources,则需在finally块中关闭流,避免资源泄露。

4. 文件复制实例

通过字节流复制文件是基础操作,涉及输入输出流的配合使用。

示例代码:

try (FileInputStream fis = new FileInputStream("source.jpg");
     FileOutputStream fos = new FileOutputStream("target.jpg")) {
    byte[] buffer = new byte[1024];
    int length;
    while ((length = fis.read(buffer)) != -1) {
        fos.write(buffer, 0, length);
    }
} catch (IOException e) {
    e.printStackTrace();
}

该示例体现缓冲数组的应用,提升复制效率。

5. 字符编码转换的输入输出流

字符流默认使用平台编码,读取或写入非默认编码文本可能出现乱码。解决方法是使用InputStreamReader和OutputStreamWriter指定编码。

示例:

try (InputStreamReader isr = new InputStreamReader(new FileInputStream("data_utf8.txt"), "UTF-8");
     BufferedReader br = new BufferedReader(isr)) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

实例分析

实例一:文本文件内容统计

背景:统计文本文件中字符数、单词数和行数,是处理文本数据的常见任务。

分析:使用BufferedReader逐行读取文件,行数递增;每行字符数累加;通过空格分割单词数。

代码示例

public class FileStatistics {
    public static void main(String[] args) {
        String filePath = "sample.txt";
        int lineCount = 0;
        int wordCount = 0;
        int charCount = 0;

        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                lineCount++;
                charCount += line.length();
                String[] words = line.trim().split("\\s+");
                if (words.length == 1 && words[0].isEmpty()) {
                    continue;
                }
                wordCount += words.length;
            }
            System.out.println("Lines: " + lineCount);
            System.out.println("Words: " + wordCount);
            System.out.println("Characters: " + charCount);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结论:合理使用缓冲字符流和字符串处理方法,实现文本统计功能,体现输入流与字符串操作结合应用。

实例二:图片文件复制与校验

背景:复制图片文件后,需要校验目标文件与源文件是否一致。

分析:使用FileInputStream和FileOutputStream复制文件,复制完后比较两个文件的字节数和MD5摘要。

核心代码片段

// 复制文件
try (FileInputStream fis = new FileInputStream("source.png");
     FileOutputStream fos = new FileOutputStream("copy.png")) {
    byte[] buffer = new byte[4096];
    int len;
    while ((len = fis.read(buffer)) != -1) {
        fos.write(buffer, 0, len);
    }
}

// 校验文件大小
File sourceFile = new File("source.png");
File copyFile = new File("copy.png");
if (sourceFile.length() == copyFile.length()) {
    System.out.println("文件大小一致,复制成功。");
} else {
    System.out.println("文件大小不一致,复制失败。");
}

结论:通过字节流完成二进制文件复制,配合文件属性校验保证复制准确。

实例三:控制台输入输出实现简单交互

背景:通过标准输入输出流实现用户输入数据并回显。

分析:使用Scanner封装System.in读取输入,使用System.out打印输出,体现流在交互中的角色。

示例代码

import java.util.Scanner;

public class ConsoleIO {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您的名字:");
        String name = scanner.nextLine();
        System.out.println("您好," + name + "!");
        scanner.close();
    }
}

结论:标准输入输出流方便实现控制台交互,Scanner是输入流的常用封装类。


常见误区

  1. 误区一:未关闭流导致资源泄漏
  • 错误做法:使用完流不调用close(),导致文件被占用或内存泄漏。
  • 正确做法:使用try-with-resources或finally块确保关闭流。
  1. 误区二:字符流处理二进制文件
  • 错误做法:用FileReader/FileWriter处理图片、音频等二进制文件,导致数据损坏。
  • 正确做法:二进制文件用字节流FileInputStream/FileOutputStream。
  1. 误区三:忽略缓冲流提升效率
  • 错误做法:直接使用FileInputStream/FileOutputStream读取大量数据,效率低。
  • 正确做法:用缓冲流包装基本流,提升性能。
  1. 误区四:忘记处理异常
  • 错误做法:IO操作不捕获异常,程序可能崩溃。
  • 正确做法:捕获并处理IOException,保证程序健壮。
  1. 误区五:错误的编码导致乱码
  • 错误做法:读取UTF-8文件时未指定编码,使用平台默认编码。
  • 正确做法:用InputStreamReader指定正确编码读取文件。

应用场景

  • 文件读写与处理:文本编辑器、配置文件读写、日志文件管理等。
  • 数据传输:网络通信数据流读取与发送。
  • 多媒体文件复制与处理:图片、音视频文件的复制、备份。
  • 用户交互:控制台输入输出实现命令行程序交互。
  • 数据转换:字符集转换、文件格式转换。

知识拓展

  • Java NIO(New IO):Java 1.4引入的非阻塞IO,提供缓冲区和通道,性能更高,适合大文件和网络应用。
  • 对象序列化流(ObjectInputStream/ObjectOutputStream):实现对象的持久化存储与传输。
  • 数据流(DataInputStream/DataOutputStream):支持Java基本数据类型的读写。
  • 文件通道(FileChannel):零拷贝技术,提高文件读写效率。
  • 异步IO(Asynchronous IO):Java 7引入,实现非阻塞异步操作。

总结回顾

本节深入讲解了输入输出流的使用,覆盖了字节流与字符流的分类、缓冲流的原理及优势、流的异常处理与关闭规范。通过多个典型实例,考生能够理解输入输出流的实际应用,掌握文件读写、数据复制、编码转换和控制台交互等重要技能。同时,列举了常见误区,帮助避免编码过程中出现的错误。掌握本节内容,将为面向对象程序设计中的文件操作和数据流处理打下坚实基础,是全国计算机等级考试四级的重要知识点。


祝学习进步!

重点知识点

1

输入输出流的基本分类:字节流与字符流

2

缓冲流的作用与使用方法

3

流的异常处理及关闭规范

4

文件读写的典型操作流程

5

字符编码转换及其重要性

6

字节流操作二进制文件,字符流操作文本文件的区别

7

流的链式包装与装饰模式

8

常见输入输出流类的应用场景

9

避免常见误区,如流未关闭、编码错误等

10

典型实例加深理解,如文件复制、文本统计和控制台交互