Java的输入输出(IO)流是处理数据读写的基础。它们允许程序与外部设备(如文件、网络等)进行数据交互。Java中的IO流主要分为字节流和字符流,每种流都有其特定的用途和类结构。
IO流的基本概念
- IO流是Java提供的一种用于处理输入输出的机制。它提供了一种统一的方式来处理不同类型的输入输出设备。
- 输入流(InputStream/Reader):用于从外部设备读取数据到程序中。
- 输出流(OutputStream/Writer):用于将程序中的数据写入到外部设备。
字节流与字符流的关系
字节流和字符流的主要区别在于处理的数据单位:
- 字节流:以字节为单位进行数据处理,适合处理二进制数据(如图片、音频等)。
- 基类:
InputStream
(输入)和OutputStream
(输出)。 - 常见子类:
FileInputStream
、FileOutputStream
、ByteArrayInputStream
、ByteArrayOutputStream
等。
- 基类:
- 字符流:以字符为单位进行数据处理,适合处理文本数据。
- 基类:
Reader
(输入)和Writer
(输出)。 - 常见子类:
FileReader
、FileWriter
、StringReader
、StringWriter
等。
- 基类:
OutputStream/Writer, InputStream/Reader这四个是所有IO流的超类,也就是父类,其他子类都是继承这四个类,下面是一张结构图,理解清除他们之间的关系方便我们更好的记忆和使用流。
字节流的使用
字节流的基本类包括InputStream
和OutputStream
。以下是它们的常用实现和示例代码:
- FileInputStream:用于从文件中读取字节数据。
- FileOutputStream:用于向文件中写入字节数据。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamExample {
public static void main(String[] args) {
// 写入数据
try (FileOutputStream fos = new FileOutputStream("example.txt")) {
String data = "Hello, Byte Stream!";
fos.write(data.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
// 读取数据
try (FileInputStream fis = new FileInputStream("example.txt")) {
int content;
while ((content = fis.read()) != -1) {
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符流的使用
字符流的基本类包括Reader
和Writer
。以下是它们的常用实现和示例代码:
- FileReader:用于从文件中读取字符数据。
- FileWriter:用于向文件中写入字符数据
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharStreamExample {
public static void main(String[] args) {
// 写入数据
try (FileWriter fw = new FileWriter("example.txt")) {
fw.write("Hello, Character Stream!");
} catch (IOException e) {
e.printStackTrace();
}
// 读取数据
try (FileReader fr = new FileReader("example.txt")) {
int content;
while ((content = fr.read()) != -1) {
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字节流与字符流的区别
IO流的其他类型
除了基本的字节流和字符流,Java IO还提供了其他类型的流,常见的包括:
- 缓冲流:如
BufferedInputStream
和BufferedOutputStream
,用于提高IO效率。 - 数据流:如
DataInputStream
和DataOutputStream
,用于读写基本数据类型。 - 打印流:如
PrintWriter
,用于格式化输出。 - 管道流:用于线程间的通信。
缓冲流
缓冲流用于提高IO效率。它们在内部使用缓冲区来减少读写操作的次数。
- BufferedInputStream:在
InputStream
基础上增加缓冲功能。 - BufferedOutputStream:在
OutputStream
基础上增加缓冲功能。
import java.io.*;
public class BufferedStreamExample {
public static void main(String[] args) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("input.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {
// 使用缓冲流进行读写操作
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
数据流
数据流用于读写基本数据类型和字符串。
- DataInputStream:用于从底层输入流中读取基本数据类型。
- DataOutputStream:用于向底层输出流中写入基本数据类型。
import java.io.*;
public class DataStreamExample {
public static void main(String[] args) {
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"))) {
dos.writeInt(42);
dos.writeDouble(3.14);
dos.writeUTF("Hello, Data Stream!");
} catch (IOException e) {
e.printStackTrace();
}
try (DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"))) {
int i = dis.readInt();
double d = dis.readDouble();
String s = dis.readUTF();
System.out.println("Integer: " + i);
System.out.println("Double: " + d);
System.out.println("String: " + s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
总结
Java中的IO流是处理数据的强大工具,字节流和字符流各有其适用场景。通过理解它们的关系和使用方式,可以高效地进行数据读写操作。对于不同类型的流,选择合适的实现类是关键。