在 Java 中,IO(Input/Output)流是用于处理数据输入输出的核心机制,它提供了一种统一的方式来读写不同类型的数据。
字节流以字节(8 位)为单位处理数据,适用于所有类型的数据(如图片、视频、二进制文件等)。
System.out
int read()
:读取单个字节,返回 0-255 的整数;若到达流末尾,返回 -1。int read(byte[] b)
:读取最多 b.length
个字节到数组 b
中,返回实际读取的字节数;若到达流末尾,返回 -1。int read(byte[] b, int off, int len)
:读取最多 len
个字节到数组 b
的 off
位置开始的部分。void close()
:关闭流,释放资源。void write(int b)
:写入单个字节(参数 b
的低 8 位)。void write(byte[] b)
:写入整个字节数组。void write(byte[] b, int off, int len)
:写入字节数组 b
中从 off
开始的 len
个字节。void flush()
:刷新缓冲区,确保数据写入目标。void close()
:关闭流,释放资源(关闭前会自动刷新)。import java.io.*;
public class FileCopyExample {
public static void main(String[] args) {
try (InputStream in = new FileInputStream("source.jpg");
OutputStream out = new FileOutputStream("target.jpg")) {
byte[] buffer = new byte[1024]; // 缓冲区大小
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
public class BufferedStreamExample {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("source.zip"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("target.zip"))) {
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
public class DataStreamExample {
public static void main(String[] args) {
try (DataOutputStream dos = new DataOutputStream(
new FileOutputStream("data.bin"))) {
dos.writeInt(123);
dos.writeDouble(3.14);
dos.writeUTF("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
try (DataInputStream dis = new DataInputStream(
new FileInputStream("data.bin"))) {
int num = dis.readInt();
double pi = dis.readDouble();
String str = dis.readUTF();
System.out.println(num); // 123
System.out.println(pi); // 3.14
System.out.println(str); // Hello, World!
} catch (IOException e) {
e.printStackTrace();
}
}
}
PrintStream
标准输出(System.out
是 PrintStream
类型)
PrintStream
提供了多种构造方法,常见的有:
PrintStream(OutputStream out)
:包装另一个输出流,不自动刷新。PrintStream(OutputStream out, boolean autoFlush)
:指定是否自动刷新。PrintStream(String fileName)
:直接输出到文件,自动刷新。PrintStream(File file)
:输出到文件对象,自动刷新。print()
:打印各种数据类型(如 int
、String
、Object
等)。println()
:打印并换行。printf()
:格式化输出,支持类似 C 语言的格式字符串。format()
:与 printf()
功能相同,更符合 Java 风格。checkError()
:检查流是否发生错误,返回 boolean
。flush()
:刷新缓冲区。close()
:关闭流。printf()
和 format()
支持格式化字符串,语法为:%[flags][width][.precision]conversion
%d
:整数(十进制)。%f
:浮点数。%s
:字符串。%c
:字符。%b
:布尔值。%n
:换行符。public class PrintStreamExample {
public static void main(String[] args) {
PrintStream ps = System.out;
// 基本打印
ps.print("Hello"); // 输出: Hello
ps.println(" World"); // 输出: World (换行)
// 格式化输出
int num = 123;
double pi = 3.14159;
ps.printf("数字: %d, 圆周率: %.2f%n", num, pi); // 输出: 数字: 123, 圆周率: 3.14
// 日期格式化
java.util.Date date = new java.util.Date();
ps.printf("日期: %tF %tT%n", date, date); // 输出: 日期: 2023-01-01 12:00:00
}
}
通过 System.setOut(PrintStream ps)
可以重定向标准输出流。
import java.io.*;
public class RedirectOutput {
public static void main(String[] args) {
try (PrintStream ps = new PrintStream(new FileOutputStream("output.txt"))) {
System.setOut(ps); // 重定向标准输出
System.out.println("This line will be written to output.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
InputStream
,用于从内存字节数组读取数据。构造方法
ByteArrayInputStream(byte[] buf)
:使用整个字节数组创建输入流。ByteArrayInputStream(byte[] buf, int offset, int length)
:使用字节数组的部分内容(从 offset
开始,长度为 length
)。OutputStream
,用于将数据写入内存字节数组。构造方法
ByteArrayOutputStream()
:创建默认初始容量的输出流(32 字节)。ByteArrayOutputStream(int size)
:创建指定初始容量的输出流。核心方法:
int read()
:读取下一个字节,返回 0-255 的整数;到达末尾返回 -1。int read(byte[] b, int off, int len)
:读取最多 len
个字节到数组 b
的 off
位置。int available()
:返回剩余可读取的字节数。void reset()
:将流的位置重置为初始位置。void mark(int readAheadLimit)
:标记当前位置(需配合 reset()
使用)。void write(int b)
:写入单个字节。void write(byte[] b, int off, int len)
:写入字节数组的部分内容。void writeTo(OutputStream out)
:将当前输出流的全部内容写入另一个输出流。byte[] toByteArray()
:返回当前输出流的内容作为字节数组。int size()
:返回当前输出流的大小(字节数)。void reset()
:清空输出流,重置为初始状态。
import java.io.*;
public class ByteArrayExample {
public static void main(String[] args) {
try {
// 创建 ByteArrayOutputStream 写入数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("Hello, World!".getBytes());
// 将 ByteArrayOutputStream 的内容转换为字节数组
byte[] data = baos.toByteArray();
// 使用 ByteArrayInputStream 读取数据
ByteArrayInputStream bais = new ByteArrayInputStream(data);
int b;
while ((b = bais.read()) != -1) {
System.out.print((char) b); // 输出: Hello, World!
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ByteArrayInputStream
和 ByteArrayOutputStream
不涉及底层资源(如文件或网络),无需调用 close()
。ByteArrayOutputStream
会在数据超过容量时自动扩容,但频繁扩容可能影响性能。