Java- IO 及其相关面试题(下)

简介: Java- IO 及其相关面试题(下)

六、 序列化和反序列化

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

相关文章
|
3月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
5月前
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
159 0
|
6月前
|
缓存 Java 关系型数据库
2025 年最新华为 Java 面试题及答案,全方位打造面试宝典
Java面试高频考点与实践指南(150字摘要) 本文系统梳理了Java面试核心考点,包括Java基础(数据类型、面向对象特性、常用类使用)、并发编程(线程机制、锁原理、并发容器)、JVM(内存模型、GC算法、类加载机制)、Spring框架(IoC/AOP、Bean生命周期、事务管理)、数据库(MySQL引擎、事务隔离、索引优化)及分布式(CAP理论、ID生成、Redis缓存)。同时提供华为级实战代码,涵盖Spring Cloud Alibaba微服务、Sentinel限流、Seata分布式事务,以及完整的D
359 1
|
5月前
|
缓存 Java API
Java 面试实操指南与最新技术结合的实战攻略
本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
475 0
|
2月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
187 1
|
4月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
5月前
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
251 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
3月前
|
算法 Java
50道java基础面试题
50道java基础面试题
|
4月前
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。