当前位置: 首页 > news >正文

3w字一文讲透Java IO

在这里插入图片描述

初识 Java IO

IO(Input / Output):指程序与外部设备之间的数据传输,如文件、网络、内存等。

Java 中使用 流(Stream) 来实现 IO 操作。

什么是流(Stream)

  • 一种数据传输通道,可以顺序读取或写入数据。

  • 流动方向:

    • 输入流(Input Stream):数据流入程序。
    • 输出流(Output Stream):数据流出程序。
  • 特性

    • 先进先出(FIFO);
    • 顺序访问;
    • 只能单向(读或写);
    • 随机访问需使用 RandomAccessFile

按传输方式划分:字节流 vs 字符流

字节与字符的区别

概念单位示例说明
字节(byte)8 位二进制10101010存储单位
字符(char)文本符号A编码后由 1~3 字节表示

UTF-8 中:英文 1 字节,中文 3 字节
Unicode 中:英文 1 字节,中文 2 字节

字节流(处理二进制)

  • 核心类:InputStreamOutputStream
  • 适用:图片、音频、视频、压缩包等
  • 方法:
int read(); 
int read(byte[] b, int off, int len);  
void write(int b);  
void write(byte[] b, int off, int len);
void flush();
void close();

示例:

try (FileInputStream fis = new FileInputStream("in.jpg");FileOutputStream fos = new FileOutputStream("out.jpg")) {byte[] buf = new byte[1024];int len;while ((len = fis.read(buf)) != -1) {fos.write(buf, 0, len);}
}

字符流(处理文本)

  • 核心类:ReaderWriter
  • 适用:文本文件(txt、xml、java等)
  • 方法:
int read();   //读取数据
int read(byte b[], int off, int len);  //从第 off 位置开始读,读取 len 长度的字节,然后放入数组 b 中
long skip(long n);   //跳过指定个数的字节
int available();   //返回可读的字节数
void close();   //关闭流,释放资源

示例:

try (FileReader fr = new FileReader("a.txt");FileWriter fw = new FileWriter("b.txt")) {char[] buf = new char[1024];int len;while ((len = fr.read(buf)) != -1) {fw.write(buf, 0, len);}
}

02. 按操作对象划分

文件流(File)

用于直接读写文件。

FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt", true); // 追加模式
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");

文件操作:

File file = new File("test.txt");
file.createNewFile();   // 创建
file.delete();          // 删除
file.renameTo(new File("new.txt")); // 重命名

内存流(数组流)

在内存中读写数据,不涉及磁盘。

ByteArrayInputStream bais = new ByteArrayInputStream("Hello".getBytes());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("World".getBytes());
byte[] result = baos.toByteArray();

内存流容量有限,适合临时数据处理(压缩、加密等)。

管道流(Piped Stream)

实现线程间通信

PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);// 写线程
new Thread(() -> {try {pos.write("Hello Pipe".getBytes());pos.close();} catch (IOException e) { e.printStackTrace(); }
}).start();// 读线程
new Thread(() -> {try {byte[] buf = new byte[1024];int len = pis.read(buf);System.out.println(new String(buf, 0, len));pis.close();} catch (IOException e) { e.printStackTrace(); }
}).start();

数据流(Data Stream)

读写基本数据类型。

// 写
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.bin"));
dos.writeInt(123);
dos.writeDouble(45.67);
dos.close();// 读
DataInputStream dis = new DataInputStream(new FileInputStream("data.bin"));
int i = dis.readInt();
double d = dis.readDouble();
dis.close();

缓冲流(Buffered)

提升读写效率。

BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
String line;
while ((line = br.readLine()) != null) {bw.write(line);bw.newLine();
}
bw.flush();
br.close();
bw.close();

缓冲流内部自带缓冲区,减少系统 IO 调用次数。

打印流(Print)

打印输出各种类型数据。

PrintStream ps = new PrintStream(new FileOutputStream("log.txt"));
ps.println("Hello IO");PrintWriter pw = new PrintWriter(new FileWriter("out.txt"));
pw.println("Java Writer");
pw.flush();

System.out 实际上是一个 PrintStream

对象流(Object Stream)

支持对象序列化与反序列化。

// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"));
oos.writeObject(new Person("张三", 20));
oos.close();// 反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"));
Person p = (Person) ois.readObject();
ois.close();

转换流(InputStreamReader / OutputStreamWriter)

桥接字节流与字符流,可指定编码。

InputStreamReader isr = new InputStreamReader(new FileInputStream("input.txt"), "UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8");

常用于解决 编码问题(防止中文乱码)。

分类输入流输出流说明
文件FileInputStreamFileOutputStream操作文件
字符文件FileReaderFileWriter操作文本
缓冲BufferedInputStream / ReaderBufferedOutputStream / Writer提高性能
数组ByteArrayInputStreamByteArrayOutputStream内存数据
管道PipedInputStreamPipedOutputStream线程通信
基本类型DataInputStreamDataOutputStream读写基本类型
对象ObjectInputStreamObjectOutputStream序列化对象
转换InputStreamReaderOutputStreamWriter字节 ⇄ 字符
打印-PrintStream / PrintWriter便捷输出

字节全能,字符专文,缓冲提速,转换连桥,数据与对象更高阶,打印最常见。

文件流详解

File 类概述

java.io.File 用于操作文件和目录(创建、删除、遍历等),不能直接操作文件内容,想读写内容,需结合 输入输出流(如 FileInputStreamFileWriter 等)。

File 构造方法

常用三种:

File(String pathname);                    // 通过路径名创建 File 实例
File(String parent, String child);         // 通过父路径(字符串)+ 子路径
File(File parent, String child);           // 通过父 File 对象 + 子路径

示例:

File file1 = new File("/Users/username/123.txt");
File file2 = new File("/Users/username/1", "2.txt");
File parentDir = new File("/Users/username/aaa");
File file3 = new File(parentDir, "bbb.txt");

路径分隔符推荐使用:

File.separator   // 自动适配操作系统的分隔符

File 类使用注意事项

  • File 对象可以表示存在或不存在的路径,构造时不会检查文件是否真实存在。
  • 一个 File 实例代表硬盘上的一个文件或目录

常用方法

1、 获取信息

getAbsolutePath();  // 返回绝对路径
getPath();          // 返回构造路径(通常与上相同)
getName();          // 文件或目录名称
length();           // 文件长度(字节数,目录时无意义)

示例:

File f = new File("/Users/username/aaa/bbb.java");
System.out.println(f.getAbsolutePath());
System.out.println(f.getName());
System.out.println(f.length());

2、 路径类型

  • 绝对路径:从系统根目录开始,如

    • Windows: C:\Program Files\Java\jdk...
    • macOS/Linux: /usr/local/bin/python3
  • 相对路径:相对于当前工作目录,如
    "config/config.properties"

3、 判断功能

exists();       // 是否存在
isDirectory();  // 是否目录
isFile();       // 是否文件

示例:

File file = new File("/Users/username/example");
if (file.exists()) { ... }
if (file.isDirectory()) { ... }
if (file.isFile()) { ... }

4、 创建与删除

createNewFile();   // 创建文件,存在则返回 false
delete();          // 删除文件或空目录
mkdir();           // 创建一级目录
mkdirs();          // 创建多级目录(常用)

示例:

File f = new File("/Users/username/example/test.txt");
f.createNewFile();
f.delete();File dir = new File("/Users/username/example/sub1/sub2");
dir.mkdirs();

5、 遍历目录

list();       // 返回子文件或目录名字符串数组
listFiles();  // 返回子文件或目录 File 对象数组

示例:

File dir = new File("/Users/username/Documents");
String[] names = dir.list();
for (String n : names) System.out.println(n);File[] files = dir.listFiles();
for (File f : files) {if (f.isFile()) System.out.println("文件:" + f.getName());if (f.isDirectory()) System.out.println("目录:" + f.getName());
}

使用前需保证路径存在且为目录,否则可能返回 null。

6、 递归遍历目录

public static void traverse(File dir) {File[] files = dir.listFiles();if (files == null) return;for (File f : files) {if (f.isFile()) System.out.println("文件:" + f.getName());else traverse(f);}
}

RandomAccessFile

RandomAccessFile 允许在文件任意位置读写(支持“随机访问”),同时支持读与写。

构造方法

RandomAccessFile(File file, String mode);
RandomAccessFile(String name, String mode);
mode含义
“r”只读
“rw”读写,不存在则创建
“rws”同步更新内容与元数据
“rwd”同步更新内容,不强制更新元数据

常用方法

long getFilePointer();             // 获取文件指针当前位置
long length();                     // 文件长度
void seek(long pos);               // 设置文件指针位置
int read();                        // 读取一个字节
int read(byte[] b, int off, int len);  // 读取字节数据
String readUTF();                  // 读取 UTF-8 字符串
void write(int b);                 // 写入一个字节
void write(byte[] b, int off, int len); // 写入字节数组
void writeUTF(String str);         // 写入 UTF-8 编码字符串

示例:写入与读取

File file = new File("logs/java/aicodehelper.txt");try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {raf.writeUTF("Hello, 一成在成长");raf.seek(0);String content = raf.readUTF();System.out.println("内容: " + content);
}

writeUTF()readUTF() 自动写入/读取长度信息,避免乱码。

Apache Commons IO - FileUtils 类

FileUtils 是 Apache Commons IO 提供的文件工具类,封装了常见操作。

常用方法

FileUtils.copyFile(src, dest);         // 复制文件
FileUtils.copyDirectory(src, dest);    // 复制目录
FileUtils.delete(file);                // 删除文件或目录
FileUtils.moveFile(src, dest);         // 移动文件
FileUtils.lastModified(file);          // 获取修改时间
FileUtils.sizeOf(file);                // 获取大小
FileUtils.getExtension(name);          // 获取文件扩展名

示例:

File src = new File("src.txt");
File dest = new File("dest.txt");
FileUtils.copyFile(src, dest);

Hutool 工具包 - FileUtil 类

FileUtil 是 Hutool 的文件操作工具类,封装了大量常用功能。

常用方法

FileUtil.copyFile(src, dest);                      // 复制文件
FileUtil.move(src, dest, true);                    // 移动文件或目录
FileUtil.del(file);                                // 删除文件或目录
FileUtil.rename(file, "newName.txt", true);        // 重命名
FileUtil.readLines(file, "UTF-8");                 // 按行读取文件

示例:

File file = new File("demo.txt");
File dest = FileUtil.file("backup.txt");
FileUtil.copyFile(file, dest);
FileUtil.readLines(file, "UTF-8").forEach(System.out::println);

字节流详解

  • 所有文件(文本、图片、视频)在计算机中都以二进制形式存储
  • 因此,字节流可以传输任意类型文件数据
  • Java 中,OutputStreamInputStream 是所有字节输出流/输入流的抽象父类。

字节输出流

基本定义

java.io.OutputStream 是所有字节输出流的超类。
常用方法:

void close();                     // 关闭流并释放资源
void flush();                     // 刷新缓冲区(强制输出)
void write(byte[] b);             // 写入整个字节数组
void write(byte[] b, int off, int len); // 从 off 开始写 len 个字节
void write(int b);                // 写入单个字节(低8位生效)

FileOutputStream 类

作用:将字节数据写入文件。

构造方法
FileOutputStream(String name);           // 通过文件名创建
FileOutputStream(File file);             // 通过文件对象创建
FileOutputStream(String name, boolean append); // 可指定是否追加
FileOutputStream(File file, boolean append);

示例:

FileOutputStream fos = new FileOutputStream("example.txt");
fos.write("一成".getBytes());
fos.close();

写入数据的方式

(1)写单个字节
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write(97);   // 写入 'a'
fos.write('b');  // 写入 'b'
fos.write('c');  // 写入 'c'
fos.close();

说明:write(int b) 只写入参数的 低8位
例如 write(0x12345678) 实际写入的是 0x78(即 'x')。

(2)写入字节数组
byte[] bytes = "一成在成长".getBytes();
FileOutputStream fos = new FileOutputStream("fos.txt");
fos.write(bytes);
fos.close();
(3)写入指定区间
byte[] data = "abcde".getBytes();
fos.write(data, 2, 2);  // 从索引2开始写2个字节,即 "cd"

追加与换行

追加写入
FileOutputStream fos = new FileOutputStream("example.txt", true); // true 表示追加
fos.write("Hello".getBytes());
fos.close();

字节输入流(InputStream)

基本定义

java.io.InputStream 是所有字节输入流的超类。
常用方法:

void close();                     // 关闭输入流
int read();                       // 读取单个字节,返回值为 0~255;到末尾返回 -1
int read(byte[] b);               // 读取多个字节到数组中
int read(byte[] b, int off, int len); // 从流中读取指定长度的字节

FileInputStream 类

作用:从文件中读取字节数据。

构造方法
FileInputStream(String name);
FileInputStream(File file);

若文件不存在,将抛出 FileNotFoundException

示例:

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

读取数据方式

(1)读取单个字节
int data;
while ((data = fis.read()) != -1) {System.out.print((char) data);
}
(2)使用字节数组读取
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {System.out.println(new String(buffer, 0, len));
}
fis.close();

文件复制示例(图片复制)

原理:读取 → 写入 → 关闭

FileInputStream fis = new FileInputStream("original.jpg");
FileOutputStream fos = new FileOutputStream("copy.jpg");byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {fos.write(buffer, 0, len);
}fis.close();
fos.close();
抽象类子类功能常用方法
InputStreamFileInputStream从文件中读取字节数据read()read(byte[])
OutputStreamFileOutputStream将字节数据写入文件write(int)write(byte[])flush()
文件复制读取 + 写入缓冲数组循环读写
  • 一切文件的本质都是二进制字节
  • FileOutputStream → 写文件;FileInputStream → 读文件;
  • write(int b) 只保留低8位;
  • 追加写需使用构造方法的第二个参数 true
  • 文件复制实质是:读入字节 → 写出字节 → 关闭流
http://www.dtcms.com/a/528371.html

相关文章:

  • 多模态学习大纲笔记(未完成)
  • 组织学习障碍:自我证明的陷阱
  • 【数据结构】顺序表的实现
  • 可以做兼职的网站质量好网站建设多少钱
  • 无声的战争:自动驾驶系统中的资源抢占、调度与生存法则
  • 30-机器学习与大模型开发数学教程-3-4 矩阵的逆与伪逆
  • 【大语言模型 104】LLM推理服务架构:从单机到分布式的演进之路
  • Rust所有权机制解析:内存安全的基石与实战指南
  • 个人做商业网站需要什么如何判断网站数据库类型
  • Spring容器进化论:从BeanFactory到ApplicationContext
  • 20.7 零样本多模态实战:CLIP模型如何让ChatPPT图像识别吞吐量飙升406%
  • 可以做平面设计兼职的网站佛山市网站建设分站哪家好
  • win11系统下配置c++机器学习库mlpack
  • [人工智能-大模型-72]:模型层技术 - 模型训练六大步:①数据预处理 - 基本功能与对应的基本组成函数
  • java基础-13 : 双列集合(Map)
  • 【十年后台管理系统】Redis的使用
  • SSM框架-MyBatis2
  • 深入理解JVM垃圾回收机制:从原理到实践
  • Spring的后处理器
  • 本地佛山顺德网站设计深圳市宝安区西乡街道
  • 监控 Linux 系统上的内存使用情况
  • 湖北省住房与建设厅网站高品质的网站开发
  • 智慧校园建设方案-6PPT(32页)
  • Spring的@Cacheable取缓存默认实现
  • MySQL-TrinityCore异步连接池的学习(七)
  • 2020应该建设什么网站建网站的论坛
  • 华为OD机考双机位A卷 - Excel单元格数值统计 (C++ Python JAVA JS GO)
  • SpringBoot集成Elasticsearch | Elasticsearch 7.x专属HLRC(High Level Rest Client)
  • 广东省住房城乡建设厅门户网站免费下载手机app
  • 信创入门指南:一文掌握信息技术应用创新的核心要点