Java- IO 及其相关面试题

news2024/10/5 22:24:57

目录

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【unity之IMGUI实践】单例模式管理面板对象【一】

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:uni…

30页PPT,IPv6技术一次梳理清

上午好,我的网工朋友。 IPv6技术在以前的文章里,已经被老杨总说的很明白了:《都到2023年了,为啥IPv6还一直无法普及? 》 但是IPv6的过渡技术,好像一直没给你补上。 你知道IPv4向IPv6过渡的步骤有哪些吗&…

在B1中定义一个纯虚函数pvf(),重做练习1-4,并解释其结果

运行代码: //在B1中定义一个纯虚函数pvf(),重做练习1-4,并解释其结果。 #include"std_lib_facilities.h" //---------------------------------------------------------------------- //定义B1类。 class B1 { public:virtual vo…

《Linux运维总结:Centos7.6之OpenSSH9.0升级版本至9.3》

一、环境信息 说明:当前环境openssh版本为9.0p1,是从7.4p1版本直接升级上来的,先需要将9.0p1版本升级至9.3p1版本。如下所示,则为源ssh和目标ssh的信息。 -操作系统openssh版本openssh安装目录openssh安装方式openssl版本openssl…

你感到迷茫吗?【笔记】

你感到迷茫吗?【笔记】 前言推荐你感到迷茫吗?原通工19级-西电电院(电子信息雷达方向-专硕三年)原计科19级-西邮计院(软件工程方向-学硕三年)原计科19级-北京360(月薪-1w)现计科20级(考研:~~不公开处理~~ 物联网)对后来…

Jmeter 分布式压测,你的系统能否承受高负载?

‍你可以使用 JMeter 来模拟高并发秒杀场景下的压力测试。这里有一个例子,它模拟了同时有 5000 个用户,循环 10 次的情况‍。 请求默认配置 如果你想学习性能测试,我这边给你推荐一套视频,这个视频可以说是B站播放全网第一的性能测…

在电脑上如何调整照片kb大小?怎么压缩图片不改变清晰度?

当我们使用图片时,如果需要压缩图片大小该怎么处理?可以使用图片压缩工具在线操作的方法解决,今天就分享一款图片在线处理工具,打开浏览器即可完成图片压缩(https://www.yasuotu.com),下面是详细…

LLaMA模型指令微调 字节跳动多模态视频大模型 Valley 论文详解

Valley: Video Assistant with Large Language model Enhanced abilitY 大家好,我是卷了又没卷,薛定谔的卷的AI算法工程师「陈城南」~ 担任某大厂的算法工程师,带来最新的前沿AI知识和工具,包括AI相关技术、ChatGPT、AI绘图等&…

性能测试工具的重要性及其应用

在现代的软件开发过程中,性能测试是不可或缺的一环。性能测试旨在评估系统或应用程序在特定负载条件下的性能表现,帮助开发团队识别潜在的性能瓶颈和问题。而性能测试工具作为辅助工具,发挥着至关重要的作用。以下是性能测试工具的重要性及其…

vue 2.0 的使用

day01 1. Vue简介 一套用于构建用户界面的 <font colorred>渐进式框架</font> 2. 初识Vue 2.1 搭建Vue开发环境 第一步&#xff1a;去<a href"https://v2.cn.vuejs.org/">Vue2官网</a>&#xff0c;下载依赖包。 第二步&#xff1a;在 …

教你如何优雅的管理UDP接口——Python

设计思路主要参考了Flask框架&#xff0c;通过 route() 装饰器来告诉 UDE触发函数的 URL&#xff0c;通过蓝图接口进行分类管理。 ude.py 代码内容 import socket import msgpackclass UDE:def __init__(self):self.urls {}# 回调函数def Callback(self, packet):try:data …

vue中elementUI表单循环验证

进行验证的步骤 1、表单el-form 添加 :model"form" ref"form" :rules"rules"&#xff0c;注意是 :model"form"不是v-model&#xff0c;而后每个el-form-item绑定prop 2、不循环的示例在官网可看 3、循环表单的验证&#xff1a;3-1、e…

QT 之蓝牙编程

简介 使用PC蓝牙和蓝牙透传模块通讯。使用Android蓝牙和蓝牙透传模块通讯。 准备 QT core gui bluetoothQT蓝牙库相关头文件 #include <QtBluetooth/qbluetoothglobal.h> #include <QtBluetooth/qbluetoothlocaldevice.h> #include <qbluetoothaddre…

6.2.5 网络基本服务----动态主机配置协议DHCP

6.2.5 网络基本服务----动态主机配置协议DHCP 动态主机配置协议允许一台计算机加入新的网络时可自动获取网络配置信息&#xff0c;不用人工参与。连网的计算机需要配置的参数包括 IP地址子网掩码默认路由器的IP地址域名服务器IP地址 DHCP与DNS、FTP、Telnet一样也采用客户服…

Jetbot TinyML Create Sin

浏览器访问ip(oled上显示的ip地址):8888&#xff0c;如192.168.10107:8888&#xff0c;Password:jetbot。 双击Notebool下的Python 3&#xff0c;然后编辑代码&#xff1a; import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import math#Well gen…

医疗器械外贸ERP软件:优化资源分配,提升企业竞争力

随着医疗器械外贸业务的不断发展&#xff0c;外贸业务管理ERP软件已经成为了医疗器械企业必不可少的一项工具。该软件解决方案可以有效地帮助企业管理海外市场、跟进海外订单、协调供应链等关键业务。 医疗器械外贸行业管理难点&#xff1a; 1、法规和标准&#xff1a;涉及到不…

博客系统(Servlet)

我们的目标是实现一个带有服务器版本的博客系统&#xff08;重点关注后端开发&#xff09; 1.准备工作 1&#xff09;创建web项目 2&#xff09;创建相应的目录结构、 3&#xff09;配置pom.xml <?xml version"1.0" encoding"UTF-8"?> <pro…

【玩转Linux操作】一文带你明白Shell的判断,循环语句

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;判断语句⭐单层if&#x1f388;示例 ⭐…

C++ 最长子段和

最大子段和详解_最大字段和_Niteip的博客-CSDN博客 #include <iostream> #include <sstream> #include <vector> #include <string> #include <algorithm> #include <climits> #include <unordered_map> #include <set>using…

ElementUI —— Cascader 级联选择器

前言&#xff1a; 项目中使用Cascader级联选择器&#xff0c;通过递归处理后端接口返回的数据。 function fn(temp) {let newArr [];for (let i 0; i < temp.length; i) {let obj {};obj.value temp[i].name;obj.label temp[i].name;obj.children [];if (temp[i].chil…