Java IO -Streams
引言
在Java编程中,IO(输入/输出)操作是与外部世界交互的基础。无论是读取用户输入、写入文件还是通过网络传输数据,IO都是不可或缺的一部分。本文将深入探讨Java IO的各个方面,帮助您掌握这一关键技术。
Java IO基础
Java IO基于两个主要的抽象: 流 (Streams)和 通道 (Channels)。流是数据传输的通道,而通道是流的源头或目的地。
Streams
字节流与字符流
字节流操作原始二进制数据,适合处理图片、音频等非文本文件。而字符流操作字符数据,并自动处理字符编码的转换,适合文本文件的处理。
字节流示例
try (FileInputStream fis = new FileInputStream("binaryfile.bin")) {
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
// 处理字节数据
} catch (IOException e) {
e.printStackTrace();
}
字符流示例
try (FileReader fr = new FileReader("textfile.txt")) {
char[] buffer = new char[1024];
int numChars;
while ((numChars = fr.read(buffer)) > 0) {
// 处理字符数据
}
} catch (IOException e) {
e.printStackTrace();
}
特殊流
对字节流或者字符流进行二次包装而产生的
缓冲流
缓冲流是字节流和字符流的包装类。缓冲流通过内部缓冲区减少物理读写次数,显著提高IO效率。BufferedInputStream
和BufferedOutputStream``BufferedReader
和BufferedWriter
可以减少实际的IO操作次数,提高效率。
缓冲流示例
try (BufferedReader br = new BufferedReader(new FileReader("textfile.txt"))) {
String line;
while ((line = br.readLine()) != null) {
// 处理每一行文本
}
} catch (IOException e) {
e.printStackTrace();
}
数据流
- 数据流是专门为了读写基本数据类型设计的,可以看作是字节流的子集,字节流的包装类。数据流可以自动处理基本数据类型的转换,如
int
、double
等 - 数据流提供了方便的方法来读取和写入基本数据类型
数据流示例
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("datafile.dat"))) {
dos.writeInt(2024);
dos.writeDouble(3.14159);
} catch (IOException e) {
e.printStackTrace();
}
对象流
对象流是字节流的扩展,提供了对对象的序列化支持,可以将对象的状态转换为字节序列,或从字节序列中恢复对象状态
对象流示例
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("objectfile.dat"))) {
MySerializableClass obj = new MySerializableClass();
oos.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
}
结构图
@startuml
skinparam classAttributeColorBackground PaleGreen
skinparam classStereotypeColor NavyBlue
class InputStream {
- int read()
...
}
class OutputStream {
- void write(int b)
...
}
class Reader {
- int read(char[] cbuf)
...
}
class Writer {
- void write(char[] cbuf, int off, int len)
...
}
class ObjectInputStream {
- T readObject()
...
}
class ObjectOutputStream {
- void writeObject(Object obj)
...
}
class FileInputStream {
+ InputStream inputStream
}
class FileOutputStream {
+ OutputStream outputStream
}
class FileReader {
+ Reader reader
}
class FileWriter {
+ Writer writer
}
class BufferedInputStream {
+ InputStream inputStream
}
class BufferedOutputStream {
+ OutputStream outputStream
}
class BufferedReader {
+ Reader reader
}
class BufferedWriter {
+ Writer writer
}
class DataInputStream {
+ InputStream inputStream
...
}
class DataOutputStream {
+ OutputStream outputStream
...
}
class Serializable {
-- 序列化接口
}
ObjectInputStream ..|> InputStream
ObjectOutputStream ..|> OutputStream
InputStream <|-- FileInputStream
OutputStream <|-- FileOutputStream
Reader <|-- FileReader
Writer <|-- FileWriter
InputStream <|-- BufferedInputStream
OutputStream <|-- BufferedOutputStream
Reader <|-- BufferedReader
Writer <|-- BufferedWriter
InputStream ..|> DataInputStream
OutputStream ..|> DataOutputStream
ObjectOutputStream .. Serializable
@enduml
总结
- 当你需要处理文本数据时,应使用字符流
- 当你需要处理二进制数据时,应使用字节流
- 当你需要提高读写效率时,可以在字节流或字符流的基础上使用缓冲流
- 当你需要读写基本数据类型时,可以使用数据流
- 当你需要将对象的状态保存到文件或通过网络传输时,应使用对象流