简单了解Java的I/O流机制与文件读写操作

一、理解Java的I/O流机制

字节流

Java中的字节流主要由 InputStreamOutputStream 这两个抽象类及其子类构成。字节流以字节(byte)为基本处理单元,适用于处理所有类型的数据,包括文本、图片、音频、视频等。

1. InputStream

InputStream 是所有字节输入流的父类。常见的子类有 FileInputStream(用于从文件中读取字节数据)、ByteArrayInputStream(从字节数组中读取数据)等。以 FileInputStream 为例,以下是从文件中读取字节数据的简单代码:

java 复制代码
import java.io.FileInputStream;
import java.io.IOException;

public class FileInputStreamExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("test.txt")) {
            int data;
            while ((data = fis.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这段代码中,fis.read() 方法每次读取一个字节的数据,返回值为读取到的字节值,当读取到文件末尾时返回 -1 。

2. OutputStream

OutputStream 是所有字节输出流的父类。常见子类有 FileOutputStream(用于向文件中写入字节数据)、ByteArrayOutputStream(将数据写入字节数组)等。以下是使用 FileOutputStream 向文件写入字节数据的代码:

java 复制代码
import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamExample {
    public static void main(String[] args) {
        String message = "Hello, Java I/O!";
        try (FileOutputStream fos = new FileOutputStream("output.txt")) {
            fos.write(message.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这里先将字符串转换为字节数组,然后通过 fos.write() 方法将字节数组写入到指定文件中。

字符流

字符流基于字节流构建,以字符(char)为基本处理单元,更适合处理文本数据。字符流由 ReaderWriter 这两个抽象类及其子类组成。

1. Reader

Reader 是所有字符输入流的父类。常见子类有 FileReader(用于从文件中读取字符数据)、BufferedReader(带有缓冲功能的字符输入流,能提高读取效率)等。使用 BufferedReader 逐行读取文件内容的代码如下:

java 复制代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReaderExample {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

br.readLine() 方法会读取文件中的一行内容并返回,当读取到文件末尾时返回 null

2. Writer

Writer 是所有字符输出流的父类。常见子类有 FileWriter(用于向文件中写入字符数据)、BufferedWriter(带有缓冲功能的字符输出流,能提高写入效率)等。下面是使用 BufferedWriter 向文件写入字符数据的代码:

java 复制代码
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterExample {
    public static void main(String[] args) {
        try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {
            bw.write("This is a line written by BufferedWriter.");
            bw.newLine();
            bw.write("Another line.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

bw.write() 方法用于写入字符数据,bw.newLine() 方法用于写入换行符。

二、熟悉文件的读写操作

文件读取操作

  1. 按字节读取 :使用 FileInputStream 逐字节读取文件,适用于读取二进制文件或对读取精度要求高的场景。但对于大文件,频繁的单个字节读取效率较低。
  2. 按字符读取 :采用 FileReader 结合 BufferedReader 逐行读取文本文件是很常见的方式。它能有效提高读取文本文件的效率,尤其适合处理大文本文件。
  3. 随机读取 :如果需要在文件的不同位置进行跳跃式读取,可以使用 RandomAccessFile 类。它既可以读取也可以写入,并且支持文件指针的随机移动。例如:
java 复制代码
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileExample {
    public static void main(String[] args) {
        try (RandomAccessFile raf = new RandomAccessFile("test.txt", "r")) {
            raf.seek(5); // 将文件指针移动到第5个字节位置
            int data;
            while ((data = raf.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

文件写入操作

  1. 覆盖写入 :使用 FileOutputStreamFileWriter 时,如果文件已存在,默认会覆盖原文件内容。如前文示例中,FileOutputStream fos = new FileOutputStream("output.txt") 就是这种情况。
  2. 追加写入 :如果希望在文件末尾追加内容,可以在创建 FileOutputStreamFileWriter 时传入第二个参数 true 。例如:
java 复制代码
import java.io.FileWriter;
import java.io.IOException;

public class AppendWriteExample {
    public static void main(String[] args) {
        try (FileWriter fw = new FileWriter("output.txt", true)) {
            fw.write("This is appended content.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

三、总结

在使用这些流的时候,要记住一点,我们是为电脑编写程序,这里的Input是指输入到电脑中,reader是指读到电脑中。一开始的时候,总是搞混这些,用久了就清楚了。

相关推荐
风逸hhh27 分钟前
python打卡day46@浙大疏锦行
开发语言·python
火兮明兮1 小时前
Python训练第四十三天
开发语言·python
季鸢1 小时前
Java设计模式之状态模式详解
java·设计模式·状态模式
@yanyu6662 小时前
springboot实现查询学生
java·spring boot·后端
ascarl20102 小时前
准确--k8s cgroup问题排查
java·开发语言
magic 2452 小时前
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
java
爱敲代码的憨仔2 小时前
分布式协同自动化办公系统-工作流引擎-流程设计
java·flowable·oa
互联网杂货铺2 小时前
完美搭建appium自动化环境
自动化测试·软件测试·python·测试工具·职场和发展·appium·测试用例
Gyoku Mint2 小时前
机器学习×第二卷:概念下篇——她不再只是模仿,而是开始决定怎么靠近你
人工智能·python·算法·机器学习·pandas·ai编程·matplotlib
纪元A梦2 小时前
分布式拜占庭容错算法——PBFT算法深度解析
java·分布式·算法