Java- IO 及其相关面试题


在这里插入图片描述

一、前言

    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. 文件创建、读取和写入

    文件的创建、读取和写入是文件操作中的基本操作。下面是一些常见的文件操作代码示例:

  1. 创建文件:
file = open("filename.txt", "w")  # 打开文件,并指定写入模式
file.close()  # 关闭文件
  1. 写入文件:
file = open("filename.txt", "w")  # 打开文件,并指定写入模式
file.write("Hello, World!")  # 写入内容
file.close()  # 关闭文件
  1. 读取文件:
file = open("filename.txt", "r")  # 打开文件,并指定读取模式
content = file.read()  # 读取文件内容
print(content)  # 打印文件内容
file.close()  # 关闭文件

4.2. 文件复制和移动

    文件复制和移动是常见的文件操作需求。可以使用shutil模块中的函数来执行文件复制和移动。

  1. 文件复制:
import shutil

src_file = "path/to/original_file.txt"
dst_file = "path/to/new_file.txt"

shutil.copy(src_file, dst_file)  # 复制文件
  1. 文件移动:
import shutil

src_file = "path/to/original_file.txt"
dst_dir = "path/to/destination_directory/"

shutil.move(src_file, dst_dir)  # 移动文件

4.3. 文件删除和重命名

文件删除和重命名也是常见的文件操作需求。

  1. 文件删除:
import os

file = "path/to/file.txt"

os.remove(file)  # 删除文件
  1. 文件重命名:
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模块的函数来获取和设置。

  1. 获取文件信息:
import os

file = "path/to/file.txt"

file_info = os.stat(file)  # 获取文件信息
print(file_info.st_size)  # 打印文件大小
print(file_info.st_mtime)  # 打印文件修改时间
  1. 设置文件权限:
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类用于创建服务器套接字。通过这些类,可以在网络上发送和接收数据。

如果本篇博客对您有一定的帮助,请留下您宝贵的三连:留言+点赞+收藏。小编在此叩谢大佬
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aqiuisme/article/details/131571823