Java IO流详解
Java IO流是Java语言中处理输入输出的机制,用于从文件、网络或其他输入源中读取输入,或将输出写入到文件、网络或其他输出源。本文将详细介绍Java IO流的概念、分类、常用类、实例、NIO流以及最佳实践等方面的内容。
一、Java IO流简介
1. 概念介绍
Java IO流是一种用于读写数据的机制,其本质是一个数据流,可以实现对文件、网络或其他输入源的读取,或将输出写入到文件、网络或其他输出源。
2. 作用说明
Java IO流是Java语言中非常重要的一个模块,其作用主要包括:
- 读取文件或网络数据。
- 将数据写入到文件或网络。
- 处理二进制数据。
- 处理字符数据。
- 实现缓冲区读写。
- 实现对象序列化和反序列化。
- 实现套接字数据传输。
二、Java IO流分类
Java IO流主要分为三类:
1. 字节流与字符流
字节流(InputStream和OutputStream)用于处理二进制数据,它们操作字节数据,即每次读/写一个字节数据。字符流(Reader和Writer)用于处理字符数据,它们操作字符数据,每次读/写一个字符。
2. 输入流与输出流
输入流(InputStream和Reader)用于接收数据,输出流(OutputStream和Writer)用于传输数据。
3. 节点流与处理流
节点流(FileInputStream、FileOutputStream、ByteArrayInputStream和ByteArrayOutputStream)是直接与输入/输出设备进行交互,对这些流的操作会影响到底层设备或文件。处理流(BufferedInputStream、BufferedOutputStream、BufferedReader和BufferedWriter)是对节点流的封装,在使用处理流的同时,底层的节点流也被一并使用。
三、Java IO流常用类
1. FileInputStream/FileOutputStream
FileInputStream用于读取文件中的数据,FileOutputStream用于向文件中写入数据。
FileInputStream fis = new FileInputStream("file.txt");
int n;
while ((n = fis.read()) != -1) {
System.out.print((char) n);
}
fis.close();
FileOutputStream fos = new FileOutputStream("file.txt");
String str = "Hello, World!";
byte[] bytes = str.getBytes();
fos.write(bytes);
fos.close();
2. FileReader/FileWriter
FileReader用于读取文件中的字符数据,FileWriter用于向文件中写入字符数据。
FileReader fr = new FileReader("file.txt");
int n;
while ((n = fr.read()) != -1) {
System.out.print((char) n);
}
fr.close();
FileWriter fw = new FileWriter("file.txt");
String str = "Hello, World!";
fw.write(str);
fw.close();
3. ByteArrayInputStream/ByteArrayOutputStream
ByteArrayInputStream用于读取内存中的字节数组,ByteArrayOutputStream用于将数据写入内存中的字节数组。
byte[] bytes = "Hello, World!".getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
int n;
while ((n = bais.read()) != -1) {
System.out.print((char) n);
}
bais.close();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String str = "Hello, World!";
byte[] bytes = str.getBytes();
baos.write(bytes);
byte[] result = baos.toByteArray();
baos.close();
System.out.println(new String(result));
4. InputStreamReader/OutputStreamWriter
InputStreamReader用于读取字符流,并将其解码为字符,OutputStreamWriter用于将字符转换为字节流。
FileInputStream fis = new FileInputStream("file.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
int n;
while ((n = isr.read()) != -1) {
System.out.print((char) n);
}
isr.close();
FileOutputStream fos = new FileOutputStream("file.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
String str = "Hello, World!";
osw.write(str);
osw.close();
5. BufferedInputStream/BufferedOutputStream
BufferedInputStream用于读取二进制数据,并将其存储到缓冲区中,BufferedOutputStream用于将数据从缓冲区写入到输出流中。
FileInputStream fis = new FileInputStream("file.txt");
BufferedInputStream bis = new BufferedInputStream(fis, 1024);
int n;
while ((n = bis.read()) != -1) {
System.out.print((char) n);
}
bis.close();
FileOutputStream fos = new FileOutputStream("file.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);
String str = "Hello, World!";
byte[] bytes = str.getBytes();
bos.write(bytes);
bos.flush();
bos.close();
6. BufferedReader/BufferedWriter
BufferedReader用于读取字符数据,并将其存储到缓冲区中,BufferedWriter用于将数据从缓冲区写入到输出流中。
FileReader fr = new FileReader("file.txt");
BufferedReader br = new BufferedReader(fr, 1024);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
FileWriter fw = new FileWriter("file.txt");
BufferedWriter bw = new BufferedWriter(fw, 1024);
String str = "Hello, World!";
bw.write(str);
bw.flush();
bw.close();
7. DataInputStream/DataOutputStream
DataInputStream用于读取二进制数据,DataOutputStream用于将数据写入二进制文件中。
FileInputStream fis = new FileInputStream("file.dat");
DataInputStream dis = new DataInputStream(fis);
int n = dis.readInt();
double d = dis.readDouble();
dis.close();
System.out.println(n + " " + d);
FileOutputStream fos = new FileOutputStream("file.dat");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(10);
dos.writeDouble(20.5);
dos.flush();
dos.close();
8. ObjectInputStream/ObjectOutputStream
ObjectInputStream用于从文件中读取对象,ObjectOutputStream用于将对象写入文件中。
FileInputStream fis = new FileInputStream("file.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
ois.close();
FileOutputStream fos = new FileOutputStream("file.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
oos.flush();
oos.close();
四、Java IO流实例
1. 文件读写
使用FileInputStream读取文件内容
FileInputStream fis = new FileInputStream("file.txt");
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
System.out.println(new String(buffer));
使用FileOutputStream向文件中写入数据
FileOutputStream fos = new FileOutputStream("file.txt", true);
String str = "追加的数据";
byte[] bytes = str.getBytes();
fos.write(bytes);
fos.close();
2. 网络传输
使用Socket传输数据
Socket socket = new Socket("127.0.0.1", 8000);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int n;
while ((n = bis.read(buffer)) != -1) {
bos.write(buffer, 0, n);
bos.flush();
}
bos.close();
bis.close();
socket.close();
使用ServerSocket接收数据
ServerSocket serverSocket = new ServerSocket(8000);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int n;
while ((n = bis.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, n));
}
bis.close();
socket.close();
serverSocket.close();
3. 字符串操作
使用StringReader读取字符串
String str = "Hello, World!";
StringReader sr = new StringReader(str);
int n;
while ((n = sr.read()) != -1) {
System.out.print((char) n);
}
sr.close();
使用StringWriter向字符串中写入数据
StringWriter sw = new StringWriter();
String str = "Hello, World!";
sw.write(str);
String result = sw.toString();
sw.close();
System.out.println(result);
4. 数组操作
使用ByteArrayInputStream读取字节数组
byte[] bytes = {1, 2, 3, 4};
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
int n;
while ((n = bais.read()) != -1) {
System.out.println(n);
}
bais.close();
使用ByteArrayOutputStream向字节数组中写入数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = {1, 2, 3, 4};
baos.write(bytes);
byte[] result = baos.toByteArray();
baos.close();
for (byte b : result) {
System.out.println(b);
}
五、Java NIO流简介
1. 概念介绍
Java NIO流(New IO)是Java SE 1.4版本引入的新型IO机制,它的目标是提供更快的、更直接的IO模型,支持异步 IO 操作和内存映射文件,以提高程序的IO性能。
2. NIO与IO的区别
NIO与IO最大的区别在于它支持对数据的非阻塞操作,这意味可以在等待IO(如读取数据)时调用其他方法,大大提高程序的效率。
3. 缓冲区、通道、选择器
NIO中的三个核心概念是缓冲区(Buffer)、通道(Channel)和选择器(Selector)。缓冲区用于存储数据,通道用于数据的传输,选择器用于多通道的管理。
六、Java IO流常见问题解决
1. 文件路径问题
文件路径问题常见于使用相对路径进行文件操作时,更好的方式是使用绝对路径,避免出现路径不正确的情况。
2. 编码问题
因为不同的编码方式在读取和写入数据时可能存在差异,建议在使用Java IO流读写文件时,指定字符集编码,如UTF-8。
3. 数据流写入读取问题
在使用Java IO流进行数据写入和读取时,需要保证写入和读取的顺序一致,否则会导致程序出错。
七、Java IO流最佳实践
1. 单独使用IO流时的实践
在单独使用IO流时,应该遵循以下最佳实践:
- 使用try-catch-finally语句块确保资源的正确释放。
- 在读写数据时指定字符集编码。
- 在文件读写时使用绝对路径。
2. 与其他代码结合时的实践
在与其他代码结合使用时,应该遵循以下最佳实践:
- 使用缓冲区优化文件读写的性能。
- 尽量避免使用过多的IO操作,可以使用for循环批量读写文件。
- 在网络传输中使用NIO流能够提高程序的效率和性能。
总结
Java IO流是Java语言中处理输入输出的机制,常用于文件读写、网络传输、字符串操作、数组操作等场景中。Java NIO流则是在Java SE 1.4版本中引入的新型IO机制,支持异步 IO 操作和内存映射文件,具有更好的性能和效率。在使用Java IO流时,应该遵循最佳实践,确保程序的正确性和性能。
文章评论