手机网站开发 html5,做网站都是花钱吗,成都网站营销seo多少费用,自己的服务器 做网站在博主的上一篇博文中#xff0c;详细的介绍了“IO”流中最基本的一些知识#xff0c;包括基本的常见的字节流和字符流#xff0c;以及对应的缓冲流#xff0c;对于“IO”流基础知识相对薄弱的同学可以先去看博主的上一篇博文Java学习之——万字详解“IO流”中基本的字节流… 在博主的上一篇博文中详细的介绍了“IO”流中最基本的一些知识包括基本的常见的字节流和字符流以及对应的缓冲流对于“IO”流基础知识相对薄弱的同学可以先去看博主的上一篇博文Java学习之——万字详解“IO流”中基本的字节流和字符流 后在回头来看这篇进阶文章效果会更好。 Java IO流中的“进阶”流转换流、序列化流、打印流和压缩流。它们构建在基础字节流和字符流之上提供了更强大、更便捷的功能。
一、转换流
1.核心概念为什么需要转换流
要理解转换流首先要明白 Java I/O 流体系中的两个核心分支
字节流以字节8 bit为基本单位处理所有类型的数据如图片、视频、音频等二进制文件也包括文本文件。基类是 InputStream 和 OutputStream。字符流以字符16 bit一个char为基本单位专门为方便处理文本数据而设计。它底层仍然是字节操作但会自动处理字符编码。基类是 Reader 和 Writer。
问题我们经常遇到这样的场景——一个字节流例如来自网络、文件的 FileInputStream 或 Socket.getInputStream()传输的是文本内容。如果我们直接使用字节流读取得到的是一个个字节我们需要自己将这些字节按照正确的字符编码如 UTF-8, GBK拼接和转换成字符非常麻烦且容易出错。
解决方案转换流InputStreamReader / OutputStreamWriter。
它们的作用就是作为一座“桥梁”将底层的字节流 转换为顶层的字符流并在转换过程中完成字节到字符的编码解码工作。
InputStreamReader 将一个字节输入流InputStream转换为一个字符输入流Reader。【解码字节 - 字符】OutputStreamWriter 将一个字符输出流Writer转换为一个字节输出流OutputStream。【编码字符 - 字节】
2.InputStreamReader 详解
核心功能InputStreamReader是 Reader的子类。它包裹着一个字节输入流InputStream并读取字节然后使用指定的或默认的字符集将其解码为字符。
关键构造函数
// 使用默认字符集创建一个 InputStreamReader
InputStreamReader(InputStream in)// 使用指定的字符集名称创建一个 InputStreamReader
// 字符集如UTF-8, GBK, ISO-8859-1
InputStreamReader(InputStream in, String charsetName)// 使用指定的 Charset 对象创建一个 InputStreamReader
InputStreamReader(InputStream in, Charset cs)
工作原理
当你调用 InputStreamReader 的 read() 方法时会发生以下步骤
它从内部的 InputStream 中读取一个或多个字节。这些字节根据构造时指定的字符集Charset进行解码。将解码后的结果以一个 char或多个 char 放入数组的形式返回。
代码示例 假设我们有一个文本文件 text.txt其编码是 GBK。如果我们用默认字符集通常是 UTF-8的 FileReader它是 InputStreamReader 的子类读取可能会乱码。使用 InputStreamReader 指定编码可以完美解决。
import java.io.*;public class InputStreamReaderDemo {public static void main(String[] args) {try (// 1. 创建一个字节流 FileInputStreamFileInputStream fis new FileInputStream(text.txt);// 2. 创建一个转换流 InputStreamReader并指定编码为 GBKInputStreamReader isr new InputStreamReader(fis, GBK);// 3. 为了高效通常用 BufferedReader 包裹 InputStreamReaderBufferedReader br new BufferedReader(isr)) {String line;// 此时读取到的字符已经是正确解码后的文本不会乱码while ((line br.readLine()) ! null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}
3.OutputStreamWriter 详解 OutputStreamWriter 是 Writer 的子类。它接收字符然后使用指定的或默认的字符集将其编码为字节并写入到底层的字节输出流OutputStream中。
关键构造函数
// 使用默认字符集创建一个 OutputStreamWriter
OutputStreamWriter(OutputStream out)// 使用指定的字符集名称创建一个 OutputStreamWriter
OutputStreamWriter(OutputStream out, String charsetName)// 使用指定的 Charset 对象创建一个 OutputStreamWriter
OutputStreamWriter(OutputStream out, Charset cs)
工作原理
当你调用 OutputStreamWriter 的 write() 方法时会发生以下步骤
你传入的字符或字符串根据构造时指定的字符集Charset进行编码。编码后得到的一个或多个字节被写入到底层的 OutputStream 中。OutputStream 最终将这些字节写入到目标文件、网络等。
我们想要将一个字符串以 GBK 编码写入到文件中。
import java.io.*;public class OutputStreamWriterDemo {public static void main(String[] args) {try (// 1. 创建一个字节流 FileOutputStreamFileOutputStream fos new FileOutputStream(output.txt);// 2. 创建一个转换流 OutputStreamWriter并指定编码为 GBKOutputStreamWriter osw new OutputStreamWriter(fos, GBK);// 3. 为了高效和方便通常用 BufferedWriter 包裹BufferedWriter bw new BufferedWriter(osw)) {String content 你好世界;bw.write(content);bw.newLine();bw.write(This is a test.);} catch (IOException e) {e.printStackTrace();}// 最终文件 output.txt 的编码将是 GBK}
}
与 FileReader / FileWriter 的关系 FileReader 本质上是 InputStreamReader 的子类它简化了文件的读取但无法指定编码只能使用默认编码。FileWriter 同理。 结论在需要明确指定编码的场合绝大多数国际化和跨平台场景不要直接使用 FileReader 和 FileWriter而应该使用 InputStreamReader 和 OutputStreamWriter 并手动指定编码。FileReader/FileWriter 仅适用于处理与系统默认编码一致的文件。