Java IO 学习总结(五)OutputStreamWriter

news2024/11/17 21:33:23

Java IO 学习总结(一)输入流/输出流
Java IO 学习总结(二)File 类
Java IO 学习总结(三)BufferedInputStream
Java IO 学习总结(四)BufferedReader 缓冲字符流
Java IO 学习总结(五)OutputStreamWriter

前言

学习IO流,记录并分享。文章如有错误,恳请指正。

类图

在这里插入图片描述

1、什么是 OutputStreamWriter?

OutputStreamWriter是字符通向字节流的桥梁:可以指定的charset将要写入流中的字符编码成字节。(编码:能看懂的字符变为看不懂的字节),关于java当中转换流,OutputStreamWriter的使用,主要是通过指定的编码表名称,来查询相对应的编码表,将字符编码为字节存储到缓冲区,再使用flush方法将内存中的文件刷新带文件中。

2、为什么要使用 OutputStreamWriter?

计算机中任何数据都是二进制储存的,不管是文本、图片还是视频,所以我们可以用字节流对所有数据进行操作,但是有时候我们又想用字符流更加便捷的操作,这个时候我们就要用到转换流了。
下面举个例子说明一下:
比方说,我们现在要读取一张相片的数据,这个时候我们应该选择用字节输入流,这样我们获得的数据就是字节的形式但是在程序中我们并不想以字节的形式储存,所以这个时候我们就需要将其转换成字符流,从而保存在字符串数组中。这里就用到InputStreamReader类,将“输入字节流”转换成“字符输入流”。同理可以理解OutputStreamWriter类的作用。

3、OutputStreamWriter 的构造函数源码

/**
 * Creates an OutputStreamWriter that uses the named charset.
 *
 * @param  out
 *         An OutputStream
 *
 * @param  charsetName
 *         The name of a supported
 *         {@link java.nio.charset.Charset charset}
 *
 * @exception  UnsupportedEncodingException
 *             If the named encoding is not supported
 */
public OutputStreamWriter(OutputStream out, String charsetName)
    throws UnsupportedEncodingException
{
    super(out);
    if (charsetName == null)
        throw new NullPointerException("charsetName");
    se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
}

/**
 * Creates an OutputStreamWriter that uses the default character encoding.
 *
 * @param  out  An OutputStream
 */
public OutputStreamWriter(OutputStream out) {
    super(out);
    try {
        se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
    } catch (UnsupportedEncodingException e) {
        throw new Error(e);
    }
}

/**
 * Creates an OutputStreamWriter that uses the given charset.
 *
 * @param  out
 *         An OutputStream
 *
 * @param  cs
 *         A charset
 *
 * @since 1.4
 * @spec JSR-51
 */
public OutputStreamWriter(OutputStream out, Charset cs) {
    super(out);
    if (cs == null)
        throw new NullPointerException("charset");
    se = StreamEncoder.forOutputStreamWriter(out, this, cs);
}

/**
 * Creates an OutputStreamWriter that uses the given charset encoder.
 *
 * @param  out
 *         An OutputStream
 *
 * @param  enc
 *         A charset encoder
 *
 * @since 1.4
 * @spec JSR-51
 */
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
    super(out);
    if (enc == null)
        throw new NullPointerException("charset encoder");
    se = StreamEncoder.forOutputStreamWriter(out, this, enc);

简单介绍:

public OutputStreamWriter(OutputStream out, String charsetName); // 创建使用指定字符集的 OutputStreamWriter。
public OutputStreamWriter(OutputStream out); // 创建使用默认字符编码(UTF-8)的 OutputStreamWriter
public OutputStreamWriter(OutputStream out, Charset cs); // 创建使用给定字符集的 OutputStreamWriter
public OutputStreamWriter(OutputStream out, CharsetEncoder enc); // 创建使用给定字符集编码器的 OutputStreamWriter。

4、OutputStreamWriter 的公共方法

public String getEncoding(); // 获取当前使用的字符编码集
void flushBuffer() throws IOException; // 在构造时设置缓冲区的大小(默认8192),当调用write时发现缓冲区剩余空间不足以写入或者调用flush()方法时,则调用flushBuffer方法使用基础流将数据写入。
public void write(int c) throws IOException; // 要写入的字符
public void write(char cbuf[], int off, int len) throws IOException;  // 要写入的字符数组
public void write(String str, int off, int len) throws IOException;  // 要写入的字符串
public void flush() throws IOException; // 将缓存区的数据刷到磁盘中
public void close() throws IOException; // 关闭该流并释放与之关联的所有资源。

重点记录下 close()这个方法:
一般情况下,数据写入缓存区后,需要使用 flush() 方法将数据刷入到硬盘中,但据我查看源码与实践发现,close()这个方法的底层实现有调用 flush() 这个方法 ,将数据刷到磁盘中,所以在你显示调用 close() 来关闭流时,可以不显示调用 flush() 这个方法。

源码如下:

// OutputStreamWriter 内部注入了 StreamEncoder 对象,close 底层实际调用的是 StreamEncoder 的 close() 方法
public class OutputStreamWriter extends Writer {
    private final StreamEncoder se;
    public void close() throws IOException {
        se.close();
    }
}
// StreamEncoder 
public class StreamEncoder extends Writer {
    public void close() throws IOException {
        synchronized(this.lock) {
            if (this.isOpen) {
                this.implClose();
                this.isOpen = false;
            }
        }
    }
void implClose() throws IOException {
    this.flushLeftoverChar((CharBuffer)null, true);
    try {
        while(true) {
            CoderResult var1 = this.encoder.flush(this.bb);
            if (var1.isUnderflow()) {
                if (this.bb.position() > 0) {
                    this.writeBytes();
                }

                if (this.ch != null) {
                    this.ch.close();
                } else {
                    this.out.close();
                }

                return;
            }

            if (var1.isOverflow()) {
                assert this.bb.position() > 0;

                this.writeBytes();
            } else {
                var1.throwException();
            }
        }
    } catch (IOException var2) {
        this.encoder.reset();
        throw var2;
    }
  }
}

5、实战

  • 使用 InputStreamReader 读取磁盘中 txt 文件内容:
/**
 * 使用 InputStreamReader 读取磁盘中 txt 文件内容
 * <p>
 * throws IOException 读取文件与关闭流的时候可能会抛出这个异常
 */
public static void readTxt() {
    // 文件路径
    String filePath = "D:/test/gls.txt";
    FileInputStream fileInputStream = null;
    InputStreamReader inputStreamReader = null;
    try {
        fileInputStream = new FileInputStream(filePath);
        // 可以不指定字符编码集, 默认 UTF-8
        inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
        // 创建一个长度为 1024 大小的 char 数组
        char chars[] = new char[1024];
        // 将字节数据读入 chars 数组中。
        int read = inputStreamReader.read(chars);
        // 打印到控制台
        System.out.println(new String(chars, 0, read));
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputStreamReader != null) {
                inputStreamReader.close();
                System.out.println("inputStreamReader 关闭该流并释放与之关联的所有资源。");
            }
            if (fileInputStream != null) {
                fileInputStream.close();
                System.out.println("fileInputStream 关闭该流并释放与之关联的所有资源。");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 向指定 txt 文件中写入内容
/**
 * 向 txt 文件中写入指定内容, 如果文件不存在, 会创建文件,不会抛出异常。
 * 但如果文件存在, 写入的内容会覆盖原文件中已有的内容,请谨慎操作!
 * <p>
 * throws IOException 读取文件与关闭流的时候可能会抛出这个异常
 */
private static void writerTxt() {
    // 文件路径
    String filePath = "D:/test/gle.txt";
    // 要写入的内容
    String content = "滚水看不到倒影,盛怒看不到真相。";
    FileOutputStream fileOutputStream = null;
    OutputStreamWriter outputStreamWriter = null;

    try {
        fileOutputStream = new FileOutputStream(filePath);
        outputStreamWriter = new OutputStreamWriter(fileOutputStream);
        // 将字符串写入到文件中, 写入指定长度的内容
        outputStreamWriter.write(content, 0, content.length());
        // 使用 flush 方法将内存中的文件刷新到文件中
        // 该方法在 close() 方法的底层中有调用,不显示调用也可以
        outputStreamWriter.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (outputStreamWriter != null) {
                outputStreamWriter.close();
                System.out.println("outputStreamWriter 关闭该流并释放与之关联的所有资源。");
            }
            if (fileOutputStream != null) {
                fileOutputStream.close();
                System.out.println("fileOutputStream 关闭该流并释放与之关联的所有资源。");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    System.out.println("执行成功");
}

Java IO 学习总结(六) 正在完善中,后续更新~


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

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

相关文章

JDK HTTPS 400错误 微软数据湖数据拉取(DataLake Landing Zone API)避坑指南

文章目录 坑1&#xff1a;微软Azure数据湖landing zone API不支持TLSv1.1协议注意JDK1.8高版本 坑2&#xff1a;拉取的文件内容开头带BOM 数据湖号称新一代数据仓库产品。数据被写进数据湖文件之后会被自动同步到landing zone&#xff0c;可以通过landing zone API读取文件内容…

一文梳理清楚 Python OpenCV 的知识体系

本篇文章为你详细罗列 Python OpenCV 的学习路线与重要知识点。核心分成 24 个小节点&#xff0c;全部掌握&#xff0c;OpenCV 入门阶段就顺利通过了。 1. OpenCV 初识与安装 本部分要了解 OpenCV &#xff08;Open Source Computer Vision Library&#xff09;的相关简介&…

常见的性能测试缺陷

目录 前言&#xff1a; 性能测试缺陷分类 一、硬件 二、网络 三、应用 四、配置 五、数据库 六、中间件 前言&#xff1a; 性能测试是测试系统在特定条件下的响应时间、并发用户数、吞吐量、内存使用率、CPU利用率、网络延迟等各项指标&#xff0c;以验证其性能是否符…

ActiveMQ消息队列的介绍以及部署

文章目录 1.ActiveMQ消息队列中间件1.1.什么是ActiveMQ1.2.ActiveMQ支持的消息传递类型 2.部署ActiveMQ消息队列2.1.安装JDK环境2.2.部署ActiveMQ消息队列2.3.启动ActiveMQ消息队列2.4.ActiveMQ的端口号2.5.使用ActiveMQ的后台管理系统 ActiveMQ官网&#xff1a;https://active…

官宣!硬核学科“集成电路与机器人应用开发”正式入驻新校区!

好消息&#xff01;好消息&#xff01; 集成电路与机器人应用开发学科 强势入驻黑马武汉校区 现在报名&#xff08;7月1日前&#xff09;首期班 限时优惠1000元 再送价值千元硬件装备1套&#xff01; 上周&#xff0c;播妞采访了几位2023届毕业生的就业现状&#xff08;点击…

11-12 - 信号发送与处理

---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;Linux系统编程训练营 - 目录 文章目录 1. 信号的概念及分类1.1 问题1.2 什么是信号1.3 信号的分类1.3.1 硬件异常信号1.3.2 终端相关信号1.3.3 软件相关信号 1.4 内核与信号1.5 …

组合模式(Composite)

别名 对象树&#xff08;Object Tree&#xff09;。 定义 组合是一种结构型设计模式&#xff0c;你可以使用它将对象组合成树状结构&#xff0c;并且能像使用独立对象一样使用它们。 前言 1. 问题 如果应用的核心模型能用树状结构表示&#xff0c;在应用中使用组合模式才…

彭博:为完善Vision Pro体验,苹果扩招数千名新员工

彭博社记者Mark Gurman在最新一期Power On栏目中表示&#xff0c;苹果在WWDC 2023上公布Vision Pro头显&#xff0c;只是该公司进入XR市场的第一步&#xff0c;实际上该设备在明年才会推出完整版。而且据项目相关人士透露&#xff0c;Vision Pro的软件生态还需要很长时间发展。…

软件工程——第6章详细设计知识点整理

本专栏是博主个人笔记&#xff0c;主要目的是利用碎片化的时间来记忆软工知识点&#xff0c;特此声明&#xff01; 文章目录 1.详细设计阶段的根本目的是&#xff1f; 2.详细设计的任务&#xff1f; 3.详细设计的结果地位&#xff1f;如何衡量程序质量&#xff1f; 4.结构程…

在GitHub上爆火!跳槽必看《Java 面试突击核心讲》知识点笔记整理

不知道大家在面试中有没有这种感觉&#xff1a;面试官通常会在短短两小时内对面试者的知识结构进行全面了解&#xff0c;面试者在回答问题时如果拖泥带水且不能直击问题的本质&#xff0c;则很难充分表现自己&#xff0c;最终影响面试结果。 所以针对这种情况&#xff0c;这份…

从0到1精通自动化测试,pytest自动化测试框架,使用自定义标记mark(十一)

一、前言 pytest可以支持自定义标记&#xff0c;自定义标记可以把一个web项目划分多个模块&#xff0c;然后指定模块名称执行 app自动化的时候&#xff0c;如果想android和ios公用一套代码时&#xff0c;也可以使用标记功能&#xff0c;标明哪些是ios用例&#xff0c;哪些是a…

除静电设备给我们的生产带来怎样的便利

一般来说&#xff0c;我们需要根据具体的生产工艺和场景选择适当的静电设备&#xff0c;并按照厂商提供的操作规范正确使用&#xff0c;以确保除静电设备有效发挥作用。 1. 静电消除&#xff1a;静电设备可以帮助消除物体表面的静电电荷&#xff0c;防止静电积聚。静电积聚可能…

UML类图设计

1.普通类&#xff0c;抽象类&#xff0c;接口 普通类 抽象类 接口 1 关联关系 依赖关系 关联&#xff1a;对象之间的引用关系 依赖&#xff1a;耦合性最低&#xff0c;一些静态方法等 2 聚合关系 组合关系 聚合&#xff1a;整体与部分的关系&#xff0c;但是部分可以脱…

英特尔 oneAPI 2023 黑客松大赛:赛道二机器学习:预测淡水质量 实践分享

目录 一、问题描述二、解决方案1、方案简述2、数据分析预处理特征类型处理特征分布分析 3、特征构造4、特征选择过滤法重要性排序 5、模型训练 总结未来工作 一、问题描述 淡水是我们最重要和最稀缺的自然资源之一&#xff0c;仅占地球总水量的 3%。它几乎触及我们日常生活的方…

Python:pyecharts可视化

文章目录 简介Geo地理图绘制折线图区域突出显示横坐标带选择展示 add地图Mapformatter控制value显示在图中显示value值目标html的解析自定义地图js资源原生地图js的解析解决省份上文字不居中的问题 桑基图设置桑基柱的颜色 参考文献 简介 &#xff08;这是20年的笔记&#xff…

医疗陪诊小程序开发功能有哪些?

医疗陪诊系统开发功能有哪些&#xff1f; 1、注册登录。用户初次使用需使用个人手机号码或者是第三方社交账号进行注册登录&#xff0c;登陆之后填写个人相关信息&#xff0c;姓名、性别、年龄、过往病史、病历等信息&#xff0c;以便医生可以根据患者资料进行初步判断。…

小文智能自定义变量详解

在小文交互场景设计时&#xff0c;有一个特殊功能&#xff0c;叫做自定义变量。有时&#xff0c;根据外呼对象的不同&#xff0c;需要对用户传达不同的内容&#xff0c;比如称呼、地址、公司名称等等。此时&#xff0c;就可以使用小文交互的自定义变量功能来实现对不同用户呼出…

Destination unreachable(Port unreachable) 错误原因和解决办法

Destination unreachable(Port unreachable) 是一条由网络设备&#xff08;如路由器或防火墙&#xff09;生成的ICMP&#xff08;Internet Control Message Protocol&#xff09;错误消息&#xff0c;用于通知源设备目标设备或端口无法到达。 一、什么是ICMP ICMP&#xff08;I…

【中危】Guava<32.0.0 存在竞争条件漏洞

漏洞描述 Guava 是 Google 公司开发的开源 Java 代码库&#xff0c;提供常用的Java工具和数据结构。 Guava 1.0 至 31.1 版本中的 FileBackedOutputStream 类使用Java的默认临时目录创建文件&#xff0c;由于创建的文件名容易被攻击者猜测&#xff0c;在 Unix 和 Android Ice…

静电设备在静电处理环节中的原理

静电设备在静电处理环节中发挥着重要的作用。以下是一些常见的静电设备及其作用&#xff1a; 1. 静电消除器&#xff1a;静电消除器通过释放相等数量的正负离子&#xff0c;有效地中和周围环境中的静电荷&#xff0c;从而减少或消除静电引起的问题&#xff0c;例如静电吸附、电…