简单了解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是指读到电脑中。一开始的时候,总是搞混这些,用久了就清楚了。

相关推荐
铁手飞鹰18 小时前
从零复现论文:深度学习域适应1
linux·pytorch·python·深度学习·ubuntu·ai·迁移学习
Leo6553519 小时前
JDK8 的排序、分组求和,转换为Map
java·开发语言
磨十三20 小时前
C++ 标准库排序算法 std::sort 使用详解
开发语言·c++·排序算法
薰衣草233321 小时前
力扣——位运算
python·算法·leetcode
书源丶1 天前
二十八、API之《System 类》——与系统交互的“桥梁”
java·交互
两只程序猿1 天前
数据可视化 | Violin Plot小提琴图Python实现 数据分布密度可视化科研图表
开发语言·python·信息可视化
Pluchon1 天前
硅基计划4.0 算法 字符串
java·数据结构·学习·算法
野生技术架构师1 天前
1000 道 Java 架构师岗面试题
java·开发语言
青柠编程1 天前
基于Spring Boot的选课管理系统架构设计
java·spring boot·后端
湫兮之风1 天前
C++: Lambda表达式详解(从入门到深入)
开发语言·c++