Java 日看一类(28)之IO包中的Flushable接口和InputStream类

本文详细介绍了Flushable接口的功能及重要方法,强调其在提高I/O速率方面的作用,并深入探讨了InputStream类作为所有字节输入流基类的设计原理与核心方法。

Flushable接口无继承类

引入了

import java.io.IOException;



该接口的类头注释如下:

/**
 * A <tt>Flushable</tt> is a destination of data that can be flushed.  The
 * flush method is invoked to write any buffered output to the underlying
 * stream.
 *
 * @since 1.5
 */

大意如下:

该类是可被输出数据输出的目标地

调用该方法可讲已缓存的输出写入底层输出流



该类含有一个方法

将缓冲推入底层流中

void flush() throws IOException;




该类的使用见前面的输出流,基本都有用到。该方法十分重要,与缓冲搭配提高IO速率;在流关闭时调用防止数据缺失等。




InputStream类无引入包

实现了Closeable接口


类头注释如下:

/**
 * This abstract class is the superclass of all classes representing
 * an input stream of bytes.
 *
 * <p> Applications that need to define a subclass of <code>InputStream</code>
 * must always provide a method that returns the next byte of input.
 *
 * @author  Arthur van Hoff
 * @see     java.io.BufferedInputStream
 * @see     java.io.ByteArrayInputStream
 * @see     java.io.DataInputStream
 * @see     java.io.FilterInputStream
 * @see     java.io.InputStream#read()
 * @see     java.io.OutputStream
 * @see     java.io.PushbackInputStream
 * @since   JDK1.0
 */

大意如下:

该抽象类是所有byte输入流的父类

应用程序需要声命该类的子类必须要提供返回输入流中下一个字节的方法



该类含有如下成员变量:

实施跳过操作时的最大缓冲区大小

private static final int MAX_SKIP_BUFFER_SIZE = 2048;




该类含有如下的成员方法:

从输入流中读取下一个字节

public abstract int read() throws IOException;

从输入流中读取该数组大小的字节

public int read(byte b[]) throws IOException {
    return read(b, 0, b.length);
}

从输入流中读取进数组特定位置,特定长度的字节

public int read(byte b[], int off, int len) throws IOException {
    if (b == null) {
        throw new NullPointerException();//空数组指针
    } else if (off < 0 || len < 0 || len > b.length - off) {//标识符越界
        throw new IndexOutOfBoundsException();
    } else if (len == 0) {
        return 0;
    }

    int c = read();
    if (c == -1) {//读取失败
        return -1;
    }
    b[off] = (byte)c;

    int i = 1;
    try {
        for (; i < len ; i++) {//重复调用读取单个字节的方法并转格式储存
            c = read();
            if (c == -1) {
                break;
            }
            b[off + i] = (byte)c;
        }
    } catch (IOException ee) {
    }
    return i;//返回实际读取长度
}

跳过后续的n个字节

public long skip(long n) throws IOException {

    long remaining = n;
    int nr;

    if (n <= 0) {//需跳过长度小于0
        return 0;
    }

    int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);//创建一个不大于最大缓冲区大小的缓冲区
    byte[] skipBuffer = new byte[size];
    while (remaining > 0) {//重复装填
        nr = read(skipBuffer, 0, (int)Math.min(size, remaining));//将跳过的字节储存进缓冲区
        if (nr < 0) {
            break;
        }
        remaining -= nr;//减去已跳过的字节
    }

    return n - remaining;//返回实际跳过大小
}

返回缓冲区中可被直接读取或跳过的估计字节数

public int available() throws IOException {
    return 0;
}

关闭流

public void close() throws IOException {}

在当前位置设置标记点(传入值为回滚上限

public synchronized void mark(int readlimit) {}

回滚

public synchronized void reset() throws IOException {
    throw new IOException("mark/reset not supported");
}

判定当前类是否支持标记回滚操作

public boolean markSupported() {
    return false;
}


该类是所有字节输入类的父类,代码内容虽然没有什么,但是体系架构方式值得我们学习

<think>首先,用户的问题是:"我想获取Java里与IO相关的面试题",意思是"我想获取Java中与IO相关的面试题"。用户提供了几个引用:[^1], [^2], [^3],这些是关于Java IO的信息。 引用内容摘要: - [^1]:提到Java IO在文件处理、网络通信、序列化中的应用。 - [^2]:列出了Java IO面试题的内容,括字节流、字符流的名,如InputStream、OutputStream、Reader、Writer,以及其他常用流如FileInputStream、BufferedReader等。 - [^3]:目录结构,涵盖了IO流简介、字节流、字符流、缓冲流、打印流等。 用户要求是基于系统指令生成相关问题,并在回答中自然地添加引用标识。系统指令指定: - 所有行内数学表达式用$...$(但这里可能不适用,因为主题是Java IO,不是数学)。 - 独立公式用$$...$$(同样,可能不适用)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识如[^1]。 用户在用户可见层说:"回答结构清晰,帮助用户逐步解决问题",所以我需要结构化回答。 用户上一次的问题是我的回答历史,但在这个对话中,我是第一次回应这个用户的问题。用户说:"上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题你的回答。" 但在这个上下文中,用户没有指定上一次问题;可能是指系统提供的示例或之前的交互。在系统指令中,有示例关于快速排序,但用户现在问的是Java IO面试题。 所以,我应该直接针对用户的当前问题响应。 关键点: - 用户想要Java IO相关的面试题。 - 引用提供了一些基础信息,我应该基于此生成问题答案。 结构回答: 1. 引入部分:解释Java IO的基本概念。 2. 列出常见的Java IO面试题。 3. 对每个面试题简要回答,基于引用。 4. 在末尾生成相关问题。 添加引用标识:当引用特定段落时,在末尾加[^1]等。 生成相关问题:在最后添加相关问题的列表。 可能的Java IO面试题: - 常见:如InputStream, OutputStream, Reader, Writer的区别。 - 文件操作:如何使用FileInputStream。 - 缓冲流:BufferedReader的好处。 - 其他:如序列化、NIO等(引用中提到序列化)。 基于引用[^2]: - JAVAIO面试题:字节输入流、字节输出流、字符输入流、字符输出流。 - 所有流实现Closeable接口。 - 输出流实现Flushable接口。 - 常用流:FileInputStream, FileOutputStream, FileReader, FileWriter, InputStreamReader, OutputStreamWriter, BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream, DataInputStream, DataOutputStream, PrintWriter, PrintStream, ObjectInputStream, ObjectOutputStream。 所以,我可以生成面试题如: 1. 解释Java IO流的概念。 2. 字节流字符流的区别是什么? 3. 为什么需要close()flush()方法? 4. 列出几个常用的Java IO。 5. 如何使用FileInputStream读取文件? 然后,对每个问题给出简要回答。 最后,生成相关问题,如: - Java NIO vs IO的区别? - 如何处理Java IO中的异常? - 等等。 确保使用中文。 回答结构: - 开头:介绍Java IO。 - 主体:列出并回答几个面试题。 - 结尾:生成相关问题列表。 自然地添加引用:当提到引用信息时,加[^1]或[^2]或[^3]。 </think>以下是根据您的请求整理的Java中与IO(输入输出)相关的常见面试题。我会基于您提供的引用资料[^1][^2][^3],结合Java IO的核心概念实际应用,构建一个结构化的回答。回答括面试题列表、简要解答(基于引用信息),并在末尾生成相关问题供您进一步学习。所有内容都使用中文,并确保引用标识自然添加在相关段落末尾。 ### Java IO相关面试题及简要解答 Java IOJava编程中处理输入输出操作的重要模块,涵盖了文件读写、网络通信、序列化等场景[^1]。以下是常见的面试题及其关键点解答(基于引用内容)。 1. **Java IO流的基本分是什么?字节流字符流有什么区别?** Java IO流主要分为字节流字符流: - **字节流**:以字节(8位)为单位读写数据,适用于所有数据型(如图像、音频)。核心括: - 输入流:`java.io.InputStream`(如`FileInputStream`用于文件读取)[^2]。 - 输出流:`java.io.OutputStream`(如`FileOutputStream`用于文件写入)[^2]。 - **字符流**:以字符(16位)为单位读写文本数据,支持Unicode编码。核心括: - 输入流:`java.io.Reader`(如`FileReader`)[^2]。 - 输出流:`java.io.Writer`(如`FileWriter`)[^2]。 区别:字节流直接处理二进制数据,适用于非文本文件;字符流处理文本文件时更高效,因为它自动处理字符编码(如UTF-8)。在Java中,名以"Stream"结尾的是字节流,以"Reader/Writer"结尾的是字符流[^2]。 2. **为什么Java IO操作中必须调用`close()``flush()`方法?请解释其作用最佳实践。** 所有Java IO流都实现了`java.io.Closeable`接口`java.io.Flushable`接口: - **`close()`方法**:用于关闭流并释放系统资源(如文件句柄或网络连接)。如果不调用,可能导致资源泄漏(例如,文件无法被其他程序访问)。最佳实践:在`finally`块或try-with-resources语句中调用确保关闭[^2],例如: ```java try (FileInputStream fis = new FileInputStream("file.txt")) { // 读取操作 } // 自动关闭资源 ``` - **`flush()`方法**:仅适用于输出流(如`OutputStream`或`Writer`),用于强制将缓冲区中的数据写入目标(如文件或网络)。如果不调用,缓冲区中的数据可能丢失(尤其在小数据量时)。最佳实践:在写入操作结束后手动调用`flush()`清空管道[^2],例如: ```java FileWriter writer = new FileWriter("output.txt"); writer.write("Hello"); writer.flush(); // 确保数据写入文件 ``` 3. **列出Java IO中常用的流,并简要说明其用途(至少5个)。** 基于引用[^2],常用流括: - `FileInputStream` / `FileOutputStream`:用于文件的字节读写操作,是最基础的文件处理[^2]。 - `FileReader` / `FileWriter`:用于文件的字符读写操作,适合文本文件[^2]。 - `BufferedReader` / `BufferedWriter`:缓冲字符流,提高读写效率(通过减少I/O次数)[^3]。 - `BufferedInputStream` / `BufferedOutputStream`:缓冲字节流,同样用于性能优化[^2]。 - `ObjectInputStream` / `ObjectOutputStream`:用于对象的序列化反序列化,支持将Java对象转换为字节流存储或传输[^2]。 这些广泛应用于文件处理、志记录网络数据传输中[^1]。 4. **什么是转换流(如InputStreamReaderOutputStreamWriter)?它们的作用是什么?** 转换流用于将字节流转换为字符流,解决编码问题: - `InputStreamReader`:将字节输入流(如`FileInputStream`)转换为字符输入流(`Reader`),允许指定字符编码(如UTF-8)。 - `OutputStreamWriter`:将字节输出流(如`FileOutputStream`)转换为字符输出流(`Writer`)。 作用:在处理文件或网络数据时,如果源数据是字节格式但需要以文本形式处理,转换流能确保正确解码编码(避免乱码)。例如,从网络套接字读取文本数据时使用[^2][^3]。 5. **Java IO中缓冲流(如BufferedReader)的优势是什么?请给出代码示例。** 缓冲流(如`BufferedReader`)通过内部缓冲区减少直接I/O操作次数,显著提升性能: - 优势:减少磁盘或网络访问次数,提高读写速度(尤其对大文件);提供便捷方法(如`readLine()`读取整行文本)[^3]。 - 代码示例: ```java try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); // 逐行读取文件 } } // 自动关闭资源 ``` 似地,`BufferedInputStream`用于字节操作[^2]。 ### 相关问题(供您进一步学习) 为了帮助您深入准备Java IO面试,我基于核心概念生成了以下相关问题: 1. Java NIO(New I/O)与传统IO的主要区别是什么?它解决了哪些性能瓶颈? 2. 如何处理Java IO操作中的异常(如IOException)?常见的最佳实践有哪些? 3. Java序列化(使用ObjectOutputStream)的原理是什么?它在分布式系统中有哪些应用场景? 4. 文件读写时,如何选择字节流(FileInputStream字符流(FileReader)?考虑因素括文件编码问题。 5. Java IO中的打印流(PrintStreamPrintWriter)有什么特点?它们与普通输出流相比的优势在哪? 如果您有具体问题(如某个面试题的详细解答或代码示例),请随时提问!我会继续基于引用资料提供可靠信息[^1][^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值