深入学习InputStream和OutputStream的使用方法,掌握Java字节流的核心概念和实际应用
字节流是Java I/O系统的基础,用于处理二进制数据。所有的字节流都继承自InputStream和OutputStream抽象类。
import java.io.*;
public class ByteStreamBasics {
// 演示FileInputStream读取文件
public static void demonstrateFileInputStream(String fileName) {
FileInputStream fis = null;
try {
fis = new FileInputStream(fileName);
// 逐字节读取
int byteData;
while ((byteData = fis.read()) != -1) {
System.out.print((char)byteData);
}
} catch (IOException e) {
System.err.println("读取文件时发生错误: " + e.getMessage());
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.err.println("关闭流时发生错误: " + e.getMessage());
}
}
}
}
// 演示FileOutputStream写入文件
public static void demonstrateFileOutputStream(String fileName, String content) {
try (FileOutputStream fos = new FileOutputStream(fileName)) {
// 将字符串转换为字节数组并写入
byte[] bytes = content.getBytes();
fos.write(bytes);
System.out.println("成功写入文件: " + fileName);
} catch (IOException e) {
System.err.println("写入文件时发生错误: " + e.getMessage());
}
}
}
缓冲流通过内置缓冲区来减少系统调用次数,显著提高I/O性能。
// 使用普通流复制文件
private static void copyFileWithNormalStream(String sourceFile, String targetFile) {
try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(targetFile)) {
int byteData;
while ((byteData = fis.read()) != -1) {
fos.write(byteData);
}
} catch (IOException e) {
System.err.println("普通流复制文件失败: " + e.getMessage());
}
}
// 使用缓冲流复制文件
private static void copyFileWithBufferedStream(String sourceFile, String targetFile) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile))) {
int byteData;
while ((byteData = bis.read()) != -1) {
bos.write(byteData);
}
} catch (IOException e) {
System.err.println("缓冲流复制文件失败: " + e.getMessage());
}
}
数据流可以直接读写Java基本数据类型,保持数据的完整性和类型信息。
// 写入不同类型的数据
public static void demonstrateDataOutput(String fileName) {
try (DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(fileName)))) {
// 写入不同类型的数据
dos.writeBoolean(true);
dos.writeByte(127);
dos.writeShort(32767);
dos.writeInt(2147483647);
dos.writeLong(9223372036854775807L);
dos.writeFloat(3.14159f);
dos.writeDouble(2.718281828459045);
dos.writeUTF("Hello, DataStream!");
System.out.println("数据写入完成");
} catch (IOException e) {
System.err.println("写入数据时发生错误: " + e.getMessage());
}
}
// 按写入顺序读取数据
public static void demonstrateDataInput(String fileName) {
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(fileName)))) {
boolean boolValue = dis.readBoolean();
byte byteValue = dis.readByte();
short shortValue = dis.readShort();
int intValue = dis.readInt();
long longValue = dis.readLong();
float floatValue = dis.readFloat();
double doubleValue = dis.readDouble();
String stringValue = dis.readUTF();
// 输出读取的数据
System.out.println("boolean: " + boolValue);
System.out.println("byte: " + byteValue);
System.out.println("short: " + shortValue);
System.out.println("int: " + intValue);
System.out.println("long: " + longValue);
System.out.println("float: " + floatValue);
System.out.println("double: " + doubleValue);
System.out.println("String: " + stringValue);
} catch (IOException e) {
System.err.println("读取数据时发生错误: " + e.getMessage());
}
}
字节数组流在内存中操作,不涉及磁盘I/O,适合临时数据处理和数据转换。
// 演示ByteArrayOutputStream的使用
public static void demonstrateByteArrayOutput() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
// 写入字符串数据
String text1 = "Hello, ";
String text2 = "ByteArrayStream!";
baos.write(text1.getBytes());
baos.write(text2.getBytes());
// 获取字节数组
byte[] data = baos.toByteArray();
System.out.println("写入的数据: " + new String(data));
System.out.println("字节数组长度: " + data.length);
System.out.println("流的大小: " + baos.size());
// 重置流
baos.reset();
System.out.println("重置后流的大小: " + baos.size());
} catch (IOException e) {
System.err.println("操作ByteArrayOutputStream时发生错误: " + e.getMessage());
} finally {
try {
baos.close();
} catch (IOException e) {
System.err.println("关闭流时发生错误: " + e.getMessage());
}
}
}
// 演示ByteArrayInputStream的使用
public static void demonstrateByteArrayInput() {
String originalText = "Java字节数组流示例";
byte[] data = originalText.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(data);
try {
System.out.println("原始数据: " + originalText);
System.out.println("可用字节数: " + bais.available());
// 批量读取
byte[] buffer = new byte[1024];
int bytesRead = bais.read(buffer);
if (bytesRead != -1) {
String readText = new String(buffer, 0, bytesRead);
System.out.println("读取的内容: " + readText);
}
} catch (IOException e) {
System.err.println("操作ByteArrayInputStream时发生错误: " + e.getMessage());
} finally {
try {
bais.close();
} catch (IOException e) {
System.err.println("关闭流时发生错误: " + e.getMessage());
}
}
}
| 流类型 | 适用场景 | 性能特点 | 使用建议 |
|---|---|---|---|
| FileInputStream/FileOutputStream | 小文件读写、简单文件操作 | 直接操作,无缓冲 | 适合小文件或一次性操作 |
| BufferedInputStream/BufferedOutputStream | 大文件读写、频繁I/O操作 | 高性能,减少系统调用 | 推荐用于大文件操作 |
| DataInputStream/DataOutputStream | 结构化数据存储、基本类型读写 | 类型安全,数据完整 | 适合配置文件、数据交换 |
| ByteArrayInputStream/ByteArrayOutputStream | 内存数据处理、临时存储 | 内存操作,速度最快 | 适合数据转换、临时缓存 |