目录
- 一、前言
- 二、Java IO 概述
- 输入和输出流
- 2.1.1 定义
- 2.1.2 代码示例
- 2.2 字节流和字符流
- 2.2.1 定义
- 2.2.2 代码示例
- 2.3 标准IO和NIO
- 三、字节流和字符流
- 3.1. 字节流:InputStream和OutputStream
- 3.1.1. FileInputStream和FileOutputStream
- 3.1.2. ByteArrayInputStream和ByteArrayOutputStream
- 3.1.3. BufferedInputStream和BufferedOutputStream
- 3.2字符流:Reader和Writer
- 3.2.1. FileReader和FileWriter:
- 3.2.2. InputStreamReader和OutputStreamWriter:
- 3.2.3. BufferedReader和BufferedWriter:
- 四、文件操作
- 4.1. 文件创建、读取和写入
- 4.2. 文件复制和移动
- 4.3. 文件删除和重命名
- 4.4. 文件属性和权限
- 五、网络通信
- 5.1. Socket编程基础
- 5.2. 服务器端示例代码
- 5.3. 客户端示例代码
- 六、 序列化和反序列化
- 6.1. Serializable接口
- 6.2 ObjectOutputStream和ObjectInputStream
- 6.3 Externalizable接口
- 七、异常处理和资源管理
- 7.1 异常处理
- 7.2 资源管理
- 八、NIO、BIO、AIO
- 8.1 什么是NIO、BIO、AIO?
- 8.2 Buffer和Channel
- 九、相关面试题
一、前言
Java IO是Java编程中非常重要的一部分,它提供了丰富的输入和输出功能,可以实现对文件、网络和其他设备的读取和写入操作。在开发中,Java IO广泛应用于文件处理、网络通信、序列化等场景。
Java IO主要涉及两个核心概念:输入流和输出流。输入流用于读取数据,输出流用于写入数据。它们支持字节流和字符流两种类型。字节流以字节为单位进行操作,适用于二进制文件或纯文本文件。字符流以字符为单位进行操作,适用于处理文本文件。
Java IO还提供了标准IO和NIO两种模式。传统的标准IO模式以流的方式进行操作,适用于较小的数据量和较低的并发处理需求。新IO(NIO)模式则基于通道和缓冲区进行操作,适用于高并发、高吞吐量的场景。
接下来,我们将详细介绍字节流和字符流的操作方法,并给出相应的代码示例。
二、Java IO 概述
输入和输出流
2.1.1 定义
输入流(InputStream)和输出流(OutputStream)是Java的I/O类库中的基本概念。输入流用于从外部源(例如文件、网络连接等)读取数据,而输出流用于将数据写入到外部目标(例如文件、网络连接等)。
输入流提供了一种逐个读取数据的方式,可以使用一些方法来读取不同类型的数据,如readByte、readChar、readInt等。输出流则提供了一些方法来写入不同类型的数据,如writeByte、writeChar、writeInt等。输入流和输出流可以用于处理各种不同的数据源和目标,例如文件、网络套接字、内存缓冲区等。
在应用中,输入流常用于读取文件内容、读取网络数据等场景,而输出流常用于将数据写入文件、将数据发送到网络等场景。
2.1.2 代码示例
下面是一个示例,演示如何使用输入流和输出流来读写文件:
import java.io.*;
public class FileIOExample {
public static void main(String[] args) {
// 读取文件内容
try (InputStream inputStream = new FileInputStream("input.txt")) {
int data = inputStream.read();
while (data != -1) {
System.out.print((char) data);
data = inputStream.read();
}
} catch (IOException e) {
e.printStackTrace();
}
// 写入文件内容
try (OutputStream outputStream = new FileOutputStream("output.txt")) {
String message = "Hello, World!";
outputStream.write(message.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2 字节流和字符流
2.2.1 定义
字节流和字符流是Java I/O类库中的两种不同类型的流。
字节流(ByteStream)以字节为单位进行读取和写入操作,可以处理任意类型的数据。字节流类库包括InputStream和OutputStream。
字符流(CharacterStream)以字符为单位进行读取和写入操作,只能处理文本类型的数据。字符流类库包括Reader和Writer。
字节流和字符流之间的主要区别在于处理的数据类型不同。字节流可以读取和写入任意类型的数据,适用于处理二进制数据和非文本数据。而字符流则专门用于处理文本数据,可以自动进行字符编码和解码,方便读写文本文件。
在选择流类型时,需要考虑到处理的数据类型。如果处理的是文本数据,应选择字符流;如果处理的是二进制数据或非文本数据,应选择字节流。
2.2.2 代码示例
下面是一个示例,演示如何使用字符流来读写文本文件:
import java.io.*;
public class FileIOExample {
public static void main(String[] args) {
// 读取文本文件内容
try (Reader reader = new FileReader("input.txt")) {
int data = reader.read();
while (data != -1) {
System.out.print((char) data);
data = reader.read();
}
} catch (IOException e) {
e.printStackTrace();
}
// 写入文本文件内容
try (Writer writer = new FileWriter("output.txt")) {
String message = "Hello, World!";
writer.write(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.3 标准IO和NIO
传统的标准IO(IO是指输入输出)是一种同步阻塞的IO模型,它使用InputStream和OutputStream来进行数据的读取和写入操作。
标准IO的特点是对数据的读取和写入是以阻塞方式进行的,意味着在IO操作完成之前,当前线程会被阻塞,无法进行其他任务。这种模型在处理大量的并发连接时,性能较差。
NIO(New IO)是Java提供的一种新的IO模型,它使用通道(Channel)和缓冲区(Buffer)来进行数据的读取和写入操作。
下面将会介绍NIO、BIO和AIO的区别以及NIO使用通道(Channel)和缓冲区(Buffer)。
三、字节流和字符流
3.1. 字节流:InputStream和OutputStream
字节流是处理字节数据的输入输出流的抽象类。常用的字节流类有FileIn putStream、FileOutputStream、ByteArrayInputStream和ByteArrayOutputStream等。
3.1.1. FileInputStream和FileOutputStream
FileInputStream和FileOutputStream是用于读取和写入文件的字节流类。
以下是一个读取文件内容并打印的示例代码:
try (FileInputStream fis = new FileInputStream("example.txt")) {
int data;
while ((data = fis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
以下是一个写入文件内容的示例代码:
try (FileOutputStream fos = new FileOutputStream("example.txt")) {
fos.write("Hello, World!".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
3.1.2. ByteArrayInputStream和ByteArrayOutputStream
ByteArrayInputStream和ByteArrayOutputStream是用于在内存中读取和写入字节数据的字节流类。
以下是一个从字节数组中读取数据并打印的示例代码:
byte[] data = {65, 66, 67, 68, 69};
try (ByteArrayInputStream bais = new ByteArrayInputStream(data)) {
int byteData;
while ((byteData = bais.read()) != -1) {
System.out.print((char) byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
以下是一个将数据写入字节数组并打印的示例代码:
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
baos.write("Hello, World!".getBytes());
byte[] data = baos.toByteArray();
System.out.println(new String(data));
} catch (IOException e) {
e.printStackTrace();
}
3.1.3. BufferedInputStream和BufferedOutputStream
BufferedInputStream和BufferedOutputStream是用于提升IO性能的装饰器类,它们通过在内部提供缓冲区来实现。
以下是一个使用BufferedInputStream读取文件的示例代码:
try (FileInputStream fis = new FileInputStream("example.txt");
BufferedInputStream bis = new BufferedInputStream(fis)) {
int data;
while ((data = bis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
以下是一个使用BufferedOutputStream写入文件的示例代码:
try (FileOutputStream fos = new FileOutputStream("example.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
bos.write("Hello, World!".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
以上是字节流的基本使用方法和示例代码。接下来,我们将介绍字符流的操作方法。
3.2字符流:Reader和Writer
3.2.1. FileReader和FileWriter:
FileReader是一个用于读取字符文件的类,而FileWriter是一个用于写入字符文件的类。
下面是使用FileReader读取字符文件和使用FileWriter写入字符文件的代码示例:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileExample {
public static void main(String[] args) {
// 使用FileReader读取字符文件
try (FileReader reader = new FileReader("input.txt")) {
int data;
while ((data = reader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用FileWriter写入字符文件
try (FileWriter writer = new FileWriter("output.txt")) {
writer.write("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,使用FileReader读取名为"input.txt"的字符文件,并将其内容打印到控制台上。接下来,使用FileWriter将字符串"Hello, World!"写入名为"output.txt"的字符文件。
3.2.2. InputStreamReader和OutputStreamWriter:
InputStreamReader是一个字符流和字节流之间的桥梁,它将字节流转换为字符流;而OutputStreamWriter是将字符流转换为字节流的类。
下面是使用InputStreamReader将字节流转换为字符流,并使用OutputStreamWriter将字符流转换为字节流的代码示例:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class StreamExample {
public static void main(String[] args) {
// 使用InputStreamReader将字节流转换为字符流
try (FileInputStream inputStream = new FileInputStream("input.txt");
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8")) {
int data;
while ((data = inputStreamReader.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用OutputStreamWriter将字符流转换为字节流
try (FileOutputStream outputStream = new FileOutputStream("output.txt");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8")) {
outputStreamWriter.write("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,使用InputStreamReader将名为"input.txt"的字节流转换为字符流,并将其内容打印到控制台上。
接下来,使用OutputStreamWriter将字符串"Hello, World!"转换为名为"output.txt"的字节流。
3.2.3. BufferedReader和BufferedWriter:
BufferedReader和BufferedWriter 是具有缓冲区功能的字符流,可以提高读取和写入字符数据的效率。
下面是使用BufferedReader读取字符文件和使用BufferedWriter写入字符文件的代码示例:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferExample {
public static void main(String[] args) {
// 使用BufferedReader读取字符文件
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用BufferedWriter写入字符文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
writer.write("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的示例中,使用BufferedReader逐行读取名为"input.txt"的字符文件,并将每行内容打印到控制台上。
通过使用BufferedReader和BufferedWriter,可以减少对磁盘的读写次数,从而提高读取和写入字符数据的效率。
四、文件操作
4.1. 文件创建、读取和写入
文件的创建、读取和写入是文件操作中的基本操作。下面是一些常见的文件操作代码示例:
- 创建文件:
file = open("filename.txt", "w") # 打开文件,并指定写入模式
file.close() # 关闭文件
- 写入文件:
file = open("filename.txt", "w") # 打开文件,并指定写入模式
file.write("Hello, World!") # 写入内容
file.close() # 关闭文件
- 读取文件:
file = open("filename.txt", "r") # 打开文件,并指定读取模式
content = file.read() # 读取文件内容
print(content) # 打印文件内容
file.close() # 关闭文件
4.2. 文件复制和移动
文件复制和移动是常见的文件操作需求。可以使用shutil模块中的函数来执行文件复制和移动。
- 文件复制:
import shutil
src_file = "path/to/original_file.txt"
dst_file = "path/to/new_file.txt"
shutil.copy(src_file, dst_file) # 复制文件
- 文件移动:
import shutil
src_file = "path/to/original_file.txt"
dst_dir = "path/to/destination_directory/"
shutil.move(src_file, dst_dir) # 移动文件
4.3. 文件删除和重命名
文件删除和重命名也是常见的文件操作需求。
- 文件删除:
import os
file = "path/to/file.txt"
os.remove(file) # 删除文件
- 文件重命名:
import os
src_file = "path/to/original_file.txt"
dst_file = "path/to/new_file.txt"
os.rename(src_file, dst_file) # 重命名文件
4.4. 文件属性和权限
文件属性和权限信息可以使用os模块的函数来获取和设置。
- 获取文件信息:
import os
file = "path/to/file.txt"
file_info = os.stat(file) # 获取文件信息
print(file_info.st_size) # 打印文件大小
print(file_info.st_mtime) # 打印文件修改时间
- 设置文件权限:
import os
file = "path/to/file.txt"
os.chmod(file, 0o777) # 设置文件权限为 777
请注意,这些代码示例仅作为基本的文件操作示例,需要根据具体的应用程序和操作系统做适当的调整。
五、网络通信
5.1. Socket编程基础
Socket编程是一种在计算机网络中进行通信的基本方式。它允许不同的计算机之间通过网络进行数据传输。
Socket编程的基本概念:
- 服务器端和客户端:在Socket编程中,通信的一方被称为服务器端,而另一方被称为客户端。服务器端通常绑定到一个特定的IP地址和端口,并在该端口上监听客户端的请求。
- IP地址和端口:IP地址是网络中唯一标识一个主机的地址,端口是用于标识一个进程的数字。
- 套接字(Socket):套接字是通信的端点,它在客户端和服务器端之间建立连接,并通过连接进行数据传输。
以下是一个简单的Socket编程示例,展示了服务器端和客户端的基本代码:
5.2. 服务器端示例代码
import java.io.File;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileNotFoundException;
public class FileOperations {
public static void main(String[] args) {
createFile();
writeFile();
readFile();
copyFile();
moveFile();
deleteFile();
renameFile();
}
public static void createFile() {
try {
File file = new File("filename.txt");
if (file.createNewFile()) {
System.out.println("File created: " + file.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
public static void writeFile() {
try {
FileWriter writer = new FileWriter("filename.txt");
writer.write("Hello, World!");
writer.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
public static void readFile() {
try {
BufferedReader reader = new BufferedReader(new FileReader("filename.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (FileNotFoundException e) {
System.out.println("File not found.");
e.printStackTrace();
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
public static void copyFile() {
File srcFile = new File("path/to/original_file.txt");
File destFile = new File("path/to/new_file.txt");
try {
Files.copy(srcFile.toPath(), destFile.toPath());
System.out.println("File copied successfully.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
public static void moveFile() {
File srcFile = new File("path/to/original_file.txt");
File destDir = new File("path/to/destination_directory/");
try {
Files.move(srcFile.toPath(), destDir.toPath().resolve(srcFile.getName()));
System.out.println("File moved successfully.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
public static void deleteFile() {
File file = new File("path/to/file.txt");
if (file.delete()) {
System.out.println("File deleted: " + file.getName());
} else {
System.out.println("Failed to delete the file.");
}
}
public static void renameFile() {
File srcFile = new File("path/to/original_file.txt");
File destFile = new File("path/to/new_file.txt");
if (srcFile.renameTo(destFile)) {
System.out.println("File renamed successfully.");
} else {
System.out.println("Failed to rename the file.");
}
}
}
5.3. 客户端示例代码
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
try {
// 创建客户端套接字
Socket clientSocket = new Socket("localhost", 8888); // 服务器的IP地址和端口号
// 发送数据给服务器
String message = "Hello, server!";
OutputStream outputStream = clientSocket.getOutputStream();
outputStream.write(message.getBytes());
// 接收服务器发送的数据
InputStream inputStream = clientSocket.getInputStream();
byte[] buffer = new byte[1024];
int length = inputStream.read(buffer);
String data = new String(buffer, 0, length);
System.out.println("收到服务器消息:" + data);
// 关闭连接
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
请注意,这些代码示例仅作为基本的Socket编程示例,并可能需要根据具体的应用程序和网络环境做适当的调整。
六、 序列化和反序列化
6.1. Serializable接口
Serializable接口是Java中的一个标记接口,它告诉Java虚拟机(JVM)这个类是可以被序列化的。序列化是将对象转换为字节流的过程,而反序列化则是将字节流转换回对象。
Serializable接口没有任何方法,因此它只是一个标记接口,表示可以被序列化和反序列化。当一个类实现Serializable接口时,JVM会自动处理该类的序列化和反序列化过程。
6.2 ObjectOutputStream和ObjectInputStream
ObjectOutputStream类将Java对象序列化到文件或网络流中。而ObjectInputStream类则用于从文件或网络流中反序列化Java对象。
下面是一个将对象序列化到文件中的示例代码:
try {
FileOutputStream fileOut = new FileOutputStream("output.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(new Person("John", 30));
out.close();
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
这个示例代码创建了一个ObjectOutputStream对象,将一个Person对象序列化到名为"output.ser"的文件中。
下面是一个从文件中反序列化Java对象的示例代码:
try {
FileInputStream fileIn = new FileInputStream("output.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Person person = (Person) in.readObject();
in.close();
fileIn.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
这个示例代码从名为"output.ser"的文件中读取一个Person对象,并将其反序列化为一个Java对象。
6.3 Externalizable接口
Externalizable接口是Serializable接口的子接口,它提供了更多的序列化和反序列化方法。Externalizable接口定义了writeExternal和readExternal方法,用于将对象序列化和反序列化到字节流中。
下面是一个使用Externalizable接口序列化和反序列化Java对象的示例代码:
try {
Person person = new Person("John", 30);
DataOutputStream out = new DataOutputStream(new FileOutputStream("output.ser"));
person.writeExternal(out);
out.close();
FileInputStream in = new FileInputStream("output.ser");
Person newPerson = new Person();
newPerson.readExternal(in);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
这个示例代码使用DataOutputStream将Person对象序列化到名为"output.ser"的文件中,然后使用DataInputStream从文件中反序列化Person对象。
七、异常处理和资源管理
7.1 异常处理
常见的IO异常包括FileNotFoundException、IOException和EOFException。在处理IO异常时,应该捕获IOException并处理它,因为它是所有IO异常的父类。
下面是一个处理IO异常的示例代码:
try {
// 执行 IO 操作
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
7.2 资源管理
在处理IO流时,应该正确地关闭流和释放资源,以避免资源泄漏。可以使用try-with-resources语句来自动关闭流,例如:
try (FileInputStream fileIn = new FileInputStream("output.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
// 读取对象
} catch (IOException e) {
e.printStackTrace();
}
这个示例代码使用try-with-resources语句创建了一个FileInputStream和一个ObjectInputStream对象,并在try块结束时自动关闭它们。这样可以确保资源被正确地释放,避免资源泄漏。
八、NIO、BIO、AIO
8.1 什么是NIO、BIO、AIO?
NIO、BIO、AIO是 Java 中不同类型的 I/O 操作。
NIO (Non-blocking I/O) 是非阻塞 I/O,它不会阻塞线程,而是在读写操作完成之后通知线程。
BIO (Blocking I/O) 是阻塞 I/O,它会在读写操作完成之前阻塞线程,等待数据读写完成。
AIO (Asynchronous I/O) 是异步 I/O,它不会阻塞线程,而是使用回调函数通知线程读写操作已完成。
维度 | BIO | NIO | AIO |
---|---|---|---|
IO模型 | 同步阻塞IO | 同步非阻塞IO | 异步非阻塞IO |
编程模型 | 基于流(Stream) | 基于缓冲区(Buffer) | 基于事件(Event) |
代码复杂度 | 简单 | 较复杂 | 最复杂 |
并发性能 | 差 | 较好 | 最好 |
可扩展性 | 差 | 较好 | 最好 |
资源消耗 | 高 | 中 | 低 |
对网络连接数 | 单线程处理多个连接 | 单线程处理多个连接 | 多线程处理多个连接 |
对操作系统支持 | 全面支持 | 仅支持较新版本 | 仅支持Linux和Windows |
应用场景 | 对并发性能要求不高的小型应用 | 对并发性能要求较高的中小型应用 | 对并发性能要求最高的大型应用 |
— | — | — | — |
IO模型 | 同步阻塞IO | 同步非阻塞IO | 异步非阻塞IO |
编程模型 | 基于流(Stream) | 基于缓冲区(Buffer) | 基于事件(Event) |
代码复杂度 | 简单 | 较复杂 | 最复杂 |
并发性能 | 差 | 较好 | 最好 |
可扩展性 | 差 | 较好 | 最好 |
资源消耗 | 高 | 中 | 低 |
对网络连接数 | 单线程处理多个连接 | 单线程处理多个连接 | 多线程处理多个连接 |
对操作系统支持 | 全面支持 | 仅支持较新版本 | 仅支持Linux和Windows |
应用场景 | 对并发性能要求不高的小型应用 | 对并发性能要求较高的中小型应用 | 对并发性能要求最高的大型应用 |
— | — | — | — |
IO模型 | 同步阻塞IO | 同步非阻塞IO | 异步非阻塞IO |
编程模型 | 基于流(Stream) | 基于缓冲区(Buffer) | 基于事件(Event) |
代码复杂度 | 简单 | 较复杂 | 最复杂 |
并发性能 | 差 | 较好 | 最好 |
可扩展性 | 差 | 较好 | 最好 |
资源消耗 | 高 | 中 | 低 |
对网络连接数 | 单线程处理多个连接 | 单线程处理多个连接 | 多线程处理多个连接 |
对操作系统支持 | 全面支持 | 仅支持较新版本 | 仅支持Linux和Windows |
应用场景 | 对并发性能要求不高的小型应用 | 对并发性能要求较高的中小型应用 | 对并发性能要求最高的大型应用 |
8.2 Buffer和Channel
Buffer是一个对象,可以存储特定类型的数据。与之相对的是Channel,它是数据的源或目标,可以与Buffer进行交互。在NIO中,数据通过Buffer在Channel之间传输。
在Java NIO中,常用的Buffer类有以下几种:
ByteBuffer: 存储字节数据
CharBuffer: 存储字符数据
ShortBuffer: 存储短整数数据
IntBuffer: 存储整数数据
LongBuffer: 存储长整数数据
FloatBuffer: 存储浮点数数据
DoubleBuffer: 存储双精度浮点数数据
Channel是与数据源或目标进行通信的对象。常用的Channel类型有:
FileChannel: 用于文件的读写操作
SocketChannel: 用于通过TCP进行网络通信
DatagramChannel:用于通过UDP进行网络通信
ServerSocketChannel: 用于监听TCP连接请求
下面是一个使用Buffer和Channel进行文件读写的示例代码:
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class FileReadWriteExample {
public static void main(String[] args) {
try {
// 打开文件输入流和输出流
FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt");
// 获取文件输入流和输出流对应的通道
FileChannel inputChannel = fis.getChannel();
FileChannel outputChannel = fos.getChannel();
// 创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 从输入通道读取数据到缓冲区
int bytesRead = inputChannel.read(buffer);
while (bytesRead != -1) {
// 切换为读模式
buffer.flip();
// 从缓冲区写入数据到输出通道
outputChannel.write(buffer);
// 清空缓冲区,准备下一次读取
buffer.clear();
// 继续从输入通道读取数据
bytesRead = inputChannel.read(buffer);
}
// 关闭通道和流
inputChannel.close();
outputChannel.close();
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
以下是关于Java IO的常用类的表格:
九、相关面试题
什么是缓冲流?为什么要使用它?
缓冲流(Buffered Stream)是一种性能优化的流,它使用缓冲区来减少对底层资源(如磁盘或网络)的访问次数,从而提高读写效率。
什么是序列化?如何实现Java对象的序列化?
序列化是将对象转换为字节流的过程,以便可以将其存储在文件中或通过网络传输。要实现Java对象的序列化,需要实现Serializable接口,并定义一个特殊的serialVersionUID字段。
如何使用Java IO进行网络编程?
可以使用Socket类和ServerSocket类来实现基于TCP/IP的网络编程。Socket类用于创建客户端套接字,ServerSocket类用于创建服务器套接字。通过这些类,可以在网络上发送和接收数据。
如果本篇博客对您有一定的帮助,请留下您宝贵的三连:留言+点赞+收藏。小编在此叩谢大佬