Java- IO 及其相关面试题

目录

  • 一、前言
  • 二、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. 文件创建、读取和写入

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

  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,它不会阻塞线程,而是使用回调函数通知线程读写操作已完成。

维度BIONIOAIO
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类用于创建服务器套接字。通过这些类,可以在网络上发送和接收数据。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/37396.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

剑指oferr68-II.二叉树的最近公共祖先

为什么这道题的难度是easy&#xff0c;我感觉挺难的啊&#xff0c;我想了挺久没有一点思路就直接看题解了。题解有两种解法&#xff0c;先看第一种存储父节点 class Solution {Map<Integer,TreeNode> parent new HashMap<Integer,TreeNode>();Set<Integer>…

【网络安全】Burpsuite v2021.12.1安装激活配置快捷启动

Burpsuite v2021.12.1安装&激活&配置&快捷启动 一、下载激活包二、配置JDK11三、启动激活 一、下载激活包 需要下载的内容&#xff1a; Burp Suite jar包JDK11激活jar包汉化jar包 下面是已经下载好的&#xff0c;可以直接使用 BurpSuite网盘下载链接 提取码&#…

【运维】第03讲(上):Nginx 负载均衡常见架构及问题解析

实际上 Nginx 除了承担代理网关角色外还会应用于 7 层应用上的负载均衡&#xff0c;本课时重点讲解 Nginx 的负载均衡应用架构&#xff0c;及最常见的问题。 学前提示 Nginx 作为负载均衡是基于代理模式的基础之上&#xff0c;所以在学习本课时前&#xff0c;你需要对 Nginx …

本地appserv外挂网址如何让外网访问?快解析端口映射

一、appserv是什么&#xff1f; AppServ 是 PHP 网页架站工具组合包&#xff0c;作者将一些网络上免费的架站资源重新包装成单一的安装程序&#xff0c;以方便初学者快速完成架站&#xff0c;AppServ 所包含的软件有&#xff1a;Apache[、Apache Monitor、PHP、MySQL、phpMyAdm…

JavaFX中MVC例子理解

JavaFX可以让你使用GUI组件创建桌面应用程序。一个GUI应用程序执行三个任务&#xff1a;接受用户的输入&#xff0c;处理输入&#xff0c;并显示输出。而一个GUI应用程序包含两个 类型的代码&#xff1a; 领域代码。处理特定领域的数据和遵循业务规范。交互代码。处理用户输入…

Elasticsearch:使用 Elasticsearch 矢量搜索和 FastAPI 构建文本搜索应用程序

在我的文章 “Elastic&#xff1a;开发者上手指南” 的 “NLP - 自然语言处理及矢量搜索”&#xff0c;我对 Elastic Stack 所提供的矢量搜索有大量的描述。其中很多的方法需要使用到 huggingface.co 及 Elastic 的机器学习。这个对于许多的开发者来说&#xff0c;意味着付费使…

【Linux】进程优先级

Linux 进程优先级 为什么要有优先级的划分&#xff1f;Linux 环境设置优先级的具体做法并发运行环境变量如何通过代码获取环境变量 环境变量的来源 为什么要有优先级的划分&#xff1f; 优先级的规定就是为了确定某种资源获取的先后顺序。 本质原因是因为CPU资源是有限的。进程…

KMP算法

KMP KMP 算法是一个快速查找匹配串的算法&#xff0c;它的作用其实就是本题问题&#xff1a;如何快速在「原字符串」中找到「匹配字符串」。 而 KMP 算法的复杂度为 O(mn)实际上是O(N),因为O(M)不可能大于O(N) KMP 之所以能够在 O(mn)复杂度内完成查找&#xff0c;是因为其能…

CentOS环境下的MYSQL8安装

MySQL 安装 参考连接&#xff1a;https://www.cnblogs.com/jasonx1an/p/16690866.html 下载 下载网址&#xff1a;https://dev.mysql.com/downloads/mysql/ 卸载 mariadb 查看 mariadb rpm -qa|grep mariadb卸载 mariadb rpm -e mariadb-libs-5.5.68-1.el7.x86_64 --nodeps再…

概率栅格

欢迎访问我的博客首页。 概率栅格 1. miss 表与 hit 表 1. miss 表与 hit 表 miss 表和 his 表是一维数组&#xff0c;它们存放的都是空闲值。其下标 i i i 代表旧空闲值&#xff0c;元素 t a b l e [ i ] table[i] table[i] 代表旧空闲值 i i i 的新空闲值。表的更新可以用…

Maven —— 项目管理工具

前言 在这篇文章中&#xff0c;荔枝会介绍如何在项目工程中借助Maven的力量来开发&#xff0c;主要涉及Maven的下载安装、环境变量的配置、IDEA中的Maven的路径配置和信息修改以及通过Maven来快速构建项目。希望能对需要配置的小伙伴们有帮助哈哈哈哈~~~ 文章目录 前言 一、初…

安全防御 --- SSL VPN

附&#xff1a;无线项目介绍 SSL VPN 有浏览器的设备就可以使用SSL&#xff0c;进而使用SSL VPN。无需担心客户端问题&#xff0c;所以SSL VPN也称为无客户端VPN。SSL VPN在client to lan场景下特别有优势。 实际实现过程&#xff08;基于TCP实现&#xff09; &#xff08;1&…

MYSQL执行一条SELECT语句的具体流程

昨天CSDN突然抽风 我一个ctrlz把整篇文章给撤掉了还不能复原 直接心态崩了不想写了 不过这部分果然还是很重要,还是写出来吧 流程图 这里面总共有两层结构Server层 储存引擎 Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现&#xff0c;主要包…

Java-API简析_java.lang.ProcessBuilder类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131729933 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

什么是Docker

容器技术和虚拟机 虚拟机 和一个单纯的应用程序相比&#xff0c;操作系统是一个很重的程序&#xff0c;刚装好的系统还什么都没有部署&#xff0c;单纯的操作系统其磁盘占用至少几十G起步&#xff0c;内存要几个G起步。 在这台机器上开启三个虚拟机&#xff0c;每个虚拟机上…

Failed to connect to github.com port 443: Connection refused问题解决

文章目录 一、问题描述&#xff1a;Failed to connect to github.com port 443: Connection refused问题解决二、解决方法一&#xff1a;排查代理问题1、尝试重置代理或者取消代理的方式2、添加全局代理 三、解决方法二&#xff1a;排查DNS解析问题1、第一步&#xff1a;查找gi…

Redis解决Session共享问题

文章目录 一、集群Session共享问题二、Redis存储验证码和对象三、解决状态登录刷新问题 一、集群Session共享问题 session共享问题&#xff1a;多台Tomcat并不共享session存储空间&#xff0c;当请求切换到不同tomcat服务器时导致数据丢失的问题 tomcat可以进行多台tomcat进行…

蓝牙技术|低功耗蓝牙和LE Audio助力游戏设备行业发展

去年&#xff0c;蓝牙技术联盟官方宣布推出LE Audio&#xff0c;它以BLE为基础&#xff0c;旨在更好地兼顾音频质量和低功耗&#xff0c;以在多种潜在应用中显著增强用户体验。这在游戏行业中引起了轰动&#xff0c;由于其延迟显著降低&#xff0c;LE Audio在增强游戏体验方面展…

连接一个JavaScript文件

● 首先&#xff0c;本章我们会使用一个起始文件&#xff0c;代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0&qu…

unidbg或者java层解密方法IDEA中打包成jar包供python调用方法

一、导出jar包方法 &#xff08;1&#xff09;配置jar包参数 &#xff08;2&#xff09;创建生成jar包 成功生成&#xff01; 二、Python代码调用 import jpypejvmPath jpype.getDefaultJVMPath() d unidbg-android.jar # 对应jar地址 jpype.startJVM(jvmPath, "-ea&q…