系列文章目录
Java文件和IO流基础部分
文件VSIO流
文章目录
- 系列文章目录
- 前言
- 一、文件的定义和理解:
1.专业定义:
2.文件系统和路径:
- 二、IO流的定义和分类
- 1.定义:
- 2.流的分类:
- 修饰器模式的核心作用:
- 基础结构:
- 总结
前言
在我们学习了前面的Java操作后,我们目前需要灵活的对文件进行灵活的操作,学习IO流是编程中的基础与核心技能,几乎所有的应用程序都涉及数据输入输出(I/O)操作。其实就是数据交互的一种方式,下面让我们详细的学习一下。
一、文件的定义与理解:
首先我先谈谈我对文件的理解。文件是保存数据的地方,比如大家经常使用的word文档,txt文件,excel文件,都是文件,它既可以保存一张图片,也可以保存视频和声音。
专业定义:
计算机文件是以计算机硬盘,光盘以及移动存储设备为载体的存储在计算机上的信息集合,其存储形式可以是文本文档,图片和程序等。文件通常具有文件扩展名,用于指示文件类型,例如,图片文件扩展名为jpg,文本文件扩展名是txt等。
文件系统和路径:
一个文件系统可以包含三类对象:文件,目录和符号链接。当今流行的操作系统都支持文件和目录,并且允许目录中包含子目录,处于目录树中最顶部的目录称为“根目录”。Linux和UNIX操作系统只有一个根目录/;而windows操作系统可以有多个根目录,例如“c:\”“d:\”等
文件系统中的对象可以使用一条路径作为唯一的识别,例如,windows系统C盘下的User目录可以表示成“C:\Users”。
路径有绝对路径和相对路径两种:
绝对路径-------从根路径开始,对文件进行完整描述,例如,“D:\data\qst.txt”。
相对路径-------从当前路径为参照,对文件进行描述,例如,“data\qst.txt”。
二、IO流的定义和分类:
1.定义:
Java的IO流是实现数据输入(Input)和输出(Output)的基础,可以对数据实现读/写操作。流的优势在于使用统一的方式对数据进行操作或传递,简化了代码的操作。
形象的理解:
可以把两端当成一个用户和物流中心,中间的就是外卖小哥,来回两个过程。
2.流的分类:
按流的流向来分:
输入流:只能从输入流中读取数据,而不能向输入流中写入数据;
输出流:只能向输出流中写入数据,而不能从输出流中读取数据;
按照流所操作的基本数据单元来分,可将流分为字节流和字符流。
核心区别在于处理数据的基本单位是字节还是字符。
分类 | 基类 | 适用场景 | 典型实现类 |
---|---|---|---|
字节流 | InputStream /OutputStream | 处理二进制数据(图片、视频、压缩包等) | FileInputStream 、ByteArrayInputStream |
字符流 | Reader /Writer | 处理文本数据(.txt 、.csv 等) | FileReader, StringWriter |
节点流和处理流:
节点流可以从一个特定的数据元读写数据。而处理流(也叫包装流)是“连接”已存在的流(节点流或处理流),为程序提供更为强大的读写功能。(更加灵活。)
我们这里详细的解释一下底层处理流:
这其实属于一种处理模式:修饰器模式(Decorator Pattern) 是一种关键设计模式,它通过动态组合对象的方式,为I/O流提供灵活的功能扩展能力,同时避免因继承导致的类爆炸问题。
修饰器模式的核心作用
-
动态扩展功能
在不修改原有类的基础上,通过嵌套包装(Wrapping)的方式,为I/O流动态添加新功能(如缓冲、压缩、加密等)。 -
避免类爆炸
如果通过继承实现所有功能组合(如缓冲+压缩+加密),需要为每个组合创建子类,导致类数量指数级增长。修饰器模式通过组合替代继承,仅需少量类即可覆盖所有功能组合。 -
保持接口一致性
所有修饰器类(如BufferedInputStream
)与基础流类(如FileInputStream
)实现相同的接口(如InputStream
),使嵌套调用透明化。
修饰器模式在Java I/O中的实现
基础结构:
- 抽象组件(Component):定义核心功能接口,如
InputStream
/OutputStream
。 - 具体组件(Concrete Component):实现基础功能,如
FileInputStream
(读取文件)。 - 修饰器抽象类(Decorator):继承自
Component
并持有Component
的引用,如FilterInputStream
。 - 具体修饰器(Concrete Decorator):添加具体功能,如
BufferedInputStream
(缓冲功能)。
// 基础组件:InputStream(抽象接口)
public abstract class InputStream {public abstract int read() throws IOException;
}// 具体组件:FileInputStream(基础文件流)
public class FileInputStream extends InputStream {public int read() { /* 从文件读取字节 */ }
}// 修饰器抽象类:FilterInputStream(所有修饰器的基类)
public class FilterInputStream extends InputStream {protected InputStream in; // 持有被修饰的流对象protected FilterInputStream(InputStream in) { this.in = in; }public int read() throws IOException { return in.read(); // 默认直接调用被修饰流的方法}
}// 具体修饰器:BufferedInputStream(添加缓冲功能)
public class BufferedInputStream extends FilterInputStream {private byte[] buffer = new byte[8192];private int pos;public BufferedInputStream(InputStream in) { super(in); }@Overridepublic int read() throws IOException {if (pos >= buffer.length) {// 从底层流批量读取数据到缓冲区int bytesRead = in.read(buffer);if (bytesRead <= 0) return -1;pos = 0;}return buffer[pos++]; // 从缓冲区返回单个字节}
}
这其实就是一种叠加的模式,你能理解吧,以下这个代码就是给大家详细说明一下:
// 基础流:读取文件
InputStream baseStream = new FileInputStream("data.txt");// 添加缓冲功能
InputStream bufferedStream = new BufferedInputStream(baseStream);// 再添加解压缩功能(假设GZIPInputStream是另一个修饰器)
InputStream gzipStream = new GZIPInputStream(bufferedStream);// 最终使用:依次调用缓冲→解压→文件读取
int data = gzipStream.read();
总结
以上就是今天要讲的内容,本文仅仅讲了文件和IO流的分类,接下来一篇我会给大家讲讲流的体系结构,以其它们是如何使用的,谢谢大家,我会持续更新的。