在计算机科学中,流(Stream) 是描述数据序列传输的抽象概念,其本质是通过有序的字节序列(或字符序列)实现数据的输入与输出。类比现实世界,流如同物流系统中的传送带:无论货物(数据)存储在仓库(文件)、运输车(网络)还是临时货架(内存)中,传送带(流)都能以统一的机制完成搬运工作。
类型 | 示例 | 流处理方式 |
---|---|---|
持久化存储 | 文本文件、图片文件 | FileInputStream |
内存数据 | 字节数组、字符串 | ByteArrayInputStream |
网络通信 | HTTP请求响应、Socket | Socket.getInputStream() |
进程间通信 | 管道数据传递 | PipedOutputStream |
程序需要从外部获取数据,就像图书馆需要从仓库调取书籍。典型场景包括:
(1)FileInputStream:基础文件字节流
// 读取图片文件的二进制数据
try (InputStream fis = new FileInputStream("photo.jpg")) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
ImageProcessor.process(buffer, bytesRead);
}
} // 自动资源管理
(2)BufferedInputStream:缓冲加速器
// 提升大文件读取效率
InputStream bis = new BufferedInputStream(
new FileInputStream("large_data.bin"), 16384); // 16KB缓冲区
(3)InputStreamReader:编码转换桥梁
// 处理UTF-8编码的文本文件
Reader reader = new InputStreamReader(
new FileInputStream("data.txt"), StandardCharsets.UTF_8);
(4)ObjectInputStream:对象序列化
// 反序列化用户对象
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("user.dat"))) {
User user = (User) ois.readObject();
}
程序产生的数据需要持久化或传输,如同工厂的产品需要包装运输。典型应用场景:
(1)FileOutputStream:基础文件写入
// 保存加密后的数据
try (OutputStream fos = new FileOutputStream("encrypted.bin")) {
byte[] encryptedData = cipher.doFinal(rawData);
fos.write(encryptedData);
}
(2)BufferedOutputStream:批量写入优化
// 高效写入日志文件
try (OutputStream bos = new BufferedOutputStream(
new FileOutputStream("app.log"))) {
for (LogEntry entry : logEntries) {
bos.write(entry.toByteArray());
}
}
(3)OutputStreamWriter:字符编码处理
// 生成CSV文件(指定GBK编码)
Writer writer = new OutputStreamWriter(
new FileOutputStream("report.csv"), "GBK");
writer.write("姓名,年龄,薪资\n");
(4)PrintStream:格式化输出
// 生成系统日志
try (PrintStream ps = new PrintStream(
new FileOutputStream("system.log"))) {
ps.printf("[%tF %,
LocalDateTime.now(), "INFO", "Service started");
}
(1)try-with-resources(推荐)
// Java 7+ 自动关闭资源
try (ZipInputStream zis = new ZipInputStream(
new FileInputStream("archive.zip"))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
processEntry(zis, entry);
}
}
(2)传统关闭方式
FileInputStream fis = null;
try {
fis = new FileInputStream("data");
// 处理逻辑
} finally {
if (fis != null) {
try { fis.close(); }
catch (IOException e) { /* 日志记录 */ }
}
}
(3)复合流关闭策略
// 关闭最外层流即可(自动关闭内层流)
try (BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
// 处理网络流
}
Java流体系采用装饰器模式(Decorator Pattern),通过组合方式扩展功能:
// 组合实现缓冲+字符转换+行读取
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new BufferedInputStream(
new FileInputStream("data.txt"))));
// 设置128KB缓冲区读取视频文件
new BufferedInputStream(new FileInputStream("video.mp4"), 131072);
try (FileChannel channel = FileChannel.open(Paths.get("bigfile.dat"))) {
ByteBuffer buffer = ByteBuffer.allocateDirect(1024*1024);
while (channel.read(buffer) > 0) {
buffer.flip();
// 处理数据
buffer.clear();
}
}
try (InputStream in = new BufferedInputStream(
new FileInputStream("source.dat"));
OutputStream out = new CipherOutputStream(
new BufferedOutputStream(
new FileOutputStream("encrypted.dat")), cipher)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) >= 0) {
out.write(buffer, 0, bytesRead);
}
}
// Spring MVC文件接收示例
@PostMapping("/upload")
public String handleUpload(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try (InputStream is = file.getInputStream();
OutputStream os = new FileOutputStream(
uploadPath + file.getOriginalFilename())) {
byte[] bytes = new byte[1024];
int readCount;
while ((readCount = is.read(bytes)) != -1) {
os.write(bytes, 0, readCount);
}
return "Upload success";
}
}
return "Upload failed";
}
通过以上系统性解析可以看出,Java流体系通过精妙的设计模式与分层抽象,实现了对不同数据源的统一操作。理解流的本质特性与正确使用方法,将显著提升程序的健壮性与执行效率。建议开发者在实际编码中结合具体场景选择合适的流类型,并严格遵守资源管理规范。