字符流的讲解 以及 Reader和Writer的用法

news2024/11/19 8:34:37

文章目录

    • ❤专栏导读
    • ❤字符流
    • ❤Reader类的操作
  • ❤Writer类操作
    • ❤Writer类的构造方法

❤专栏导读

🚀《多线程》
🚀《数据结构剖析》
🚀《JavaSE语法》

在Java标准库中,提供的读写文件的流对象有很多很多的类,但是可以将这么多的类总结成两个大的方向就是:字节流、字符流,而字节流就是针对于二进制文件进行读写操作,字符流就是针对文本文件进行读写操作

❤字符流

使用字符流,读写操作是以字符为单位的,每次最少读/写一个字符,而一个字符是多少个字节,就取决于当前的字符集是哪一种;

GBK字符集:一个中文字符是两个字节,一个英文字符是一个字节

UTF8字符集:一个中文字符是三个字节,一个英文字符是一个字节

其实,字符流是针对字节流又进行了一次封装,因为,在硬盘中,所有的文件都是以字节为单位进行保存的,都是二进制数据,但是,使用字符流的话,会将几个连续的字节给翻译成对应的字符,也就相当于自动帮我们完成了一个查字符集表的操作;

针对于字符流的操作,Java实现Reader(输入) 和 Writer(输出) 两个父类

什么叫输入(读),什么叫输出(写)?

假如,我向硬盘中保存一份内容,那么这是输入还是输出呢?

如果是站在硬盘的角度,向硬盘中保存一份内容,那么这就是输入(读),从硬盘中拿走一份数据, 那么这就是输出(写)

如果是站在操作系统的角度,向硬盘中保存一份内容,那么就是输出(写), 从硬盘中拿走一份数据,这就是输入(读)

但是,我们程序员一定要站在操作系统的角度去看,不要站在硬盘的角度看

❤Reader类的操作

  public static void main(String[] args) throws FileNotFoundException {
       Reader reader = new FileReader("d:/新建文件夹/text.txt");
       //因为Reader类是一个抽象类,所以只能new它的子类
    }
返回值类型方法说明
intread()无参数,一次读取一个字符
intread(char[] cbuf)一次读取若干字符,尽量把字符数组填满
intread(char[] cbuf,int off, int len)一次读取若干个字符,尽量将数组中,从off这个位置开始放数据,最多放len个

💡==注意点一:==为什么这个无参数的read()方法是一个int类型?

因为,这里是用了0-65536范围的数表示一个char类型的字符,因为0-65535是一个无符号的char,所以使用int类型足够表示,但是这里为什么要用int表示呢?因为是为了区分当前读操作是否读到了文件内容的末尾,如果读到了内容末尾,就返回一个-1表示已经读完了,这一点在方法说明中也可以看到;

在这里插入图片描述

💡==注意点二:==因为read()读取的是两个字节,如果是Unicode字符集编码,那么不会出现问题,但如果是UTF8字符集编码的话,一个中文字符是3个字节,这样的话不就会出现bug么,针对于这个问题,Java内部也是解决的非常好的,因为,在Java中,如果只使用char的话,那么字符集使用的就是Unicode,但是如果使用String,大概率使用的就是UTF8, 因为,是否是UTF8编码这个事情呢,是可配置的,但是char的话,固定就是Unicode,而举个例子。

假如有char[] 数组,这个数组固定使用的就是Unicode编码,如果使用这个数组构建字符串时,Java内部就会将Unicode编码转变为UTF8编码,如果有一个字符串s,使用s.charAt(0),拿到一个字符时,就会将UTF8编码转变成Unicode

接下来就演示一下读操作,将记事本中的所有内容读出来;

1.无参数read()

    public static void main(String[] args) throws IOException {
       Reader reader = new FileReader("d:/新建文件夹/text.txt");

        while(true) {
            int n = reader.read();
            if(n == -1) {
                //表示已经读完,退出循环
                break;
            }
            char ch = (char) n;
            System.out.print(ch);
        }
    }

2.带有指定数组的read()

    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("d:/新建文件夹/text.txt");
        while(true) {
            char[] cbuf = new char[1024];
            //这里定义了一个大小为1024的数组,读取时会尽量给这个数组填满,
            int n = reader.read(cbuf);
            if(n == -1) {
                System.out.println(n);
                break;
            }
            System.out.println(n);
            for(int i = 0; i < n; i++) {
                System.out.print(cbuf[i] + " ");
            }
            System.out.println();
        }
    }

3.带有三个参数的read()

public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("d:/新建文件夹/text.txt");
        while(true) {
            char[] cbuf = new char[10];
            int n = reader.read(cbuf, 2, 8);
            //从2下标开始放数据,最多放8个数据
            if(n == -1) {
                System.out.println(n);
                break;
            }
            System.out.println(n);
            for(int i = 0; i < cbuf.length; i++) {
                System.out.print(cbuf[i]);
            }
            System.out.println();
        }
    }

在这里插入图片描述

💡==注意点三:==对于流操作,使用完之后,**一定要记得调用 close() 释放文件描述符表,**而这个文件描述符表是一个类似于数组这样的结构,因为一个进程每打开一个文件,就会在这个数组中占一个位置,但是,这个数组是有容量限制的,所以,如果一直打开文件,而不关闭文件,就会使这个表中的元素越来越多,一直到把这个数组占满,后续再打开文件时,就会出错,所以就构成了文件资源泄露 !!!

    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("d:/新建文件夹/text.txt");
        //第一种,使用try、finally释放文件资源的方式
        try{
            while(true) {
                char[] cbuf = new char[10];
                int n = reader.read(cbuf, 2, 8);
                if (n == -1) {
                    System.out.println(n);
                    break;
                }
                System.out.println(n);
                for (int i = 0; i < cbuf.length; i++) {
                    System.out.print(cbuf[i]);
                }
                System.out.println();
            }
        }finally {
            //使用finally,防止代码中万一抛出异常,导致执行不到close();
            reader.close();
        }
        
        //第二种,使用try释放文件资源的方式
        //1.这个语法的目的就是,()定义的变量会在try里面的代码执行结束后,自动调用close()
        //2.只用实现Closeable接口的对象才能放再try()中
                try(Reader reader = new FileReader("d:/新建文件夹/text.txt")){
            while(true) {
                char[] cbuf = new char[10];
                int n = reader.read(cbuf, 2, 8);
                if (n == -1) {
                    System.out.println(n);
                    break;
                }
                System.out.println(n);
                for (int i = 0; i < cbuf.length; i++) {
                    System.out.print(cbuf[i]);
                }
                System.out.println();
            }
        }
    }

❤Writer类操作

    public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("d:/新建文件夹/text.txt");
    }

❤Writer类的构造方法

构造方法说明
write(int c)一次写入一个字符
write(char[] cbuf)一次写入一个字符数组中的内容
write(String str)一次写入一个字符串
write(String str, int off, int len)写入一个字符串,从字符串中的off位置开始写,写len个长度的字符
write(char[] cbuf, int off, int len)写入一个字符数组,从数组中的off位置开始写,写len个长度的字符

Writer中这些构造方法和Reader中构造方法的使用都是类似的,这里就不一一的演示了,只为大家举一个常用的

    public static void main(String[] args) throws IOException {
        try(Writer writer = new FileWriter("d:/新建文件夹/text.txt")) {
            writer.write("你真的好帅");
        }
    }

在这里插入图片描述

💡==注意点:==这里使用write向文件中写入内容时,会将原来文件中的内容覆盖掉,如果不想覆盖,在new FileWriter时传入一个true

Writer writer = new FileWriter("d:/新建文件夹/text.txt", true)

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

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

相关文章

盘点49个Python网站项目Python爱好者不容错过

盘点49个Python网站项目Python爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1aFYJtNZjgst1l5KFBckP2A?pwd8888 提取码&#xff1a;8888 项目名称 A simpleshorturl…

C++ vector中capacity()和size() 的区别

文章目录 1 capacity()和size() 介绍2 vector满了之后&#xff0c;capacity()会自动了扩充为原来的2倍 &#xff1f; 1 capacity()和size() 介绍 size是指容器当前拥有元素的个数&#xff0c; capacity是指容器在必须分配新的存储空间之前可以存放的元素总数。 如vector<i…

PasswordPusher:能通过URL安全传递密码

什么是 Password Pusher &#xff1f; Password Pusher 是一个开源应用程序&#xff0c;用于通过网络安全的传递密码。在经过一定数量的查看和/或时间后&#xff0c;指向密码的链接会过期。 从功能上说&#xff0c;类似于 Bitwarden Send&#xff0c;思路上与传统阅后即焚工具一…

智能电网线路阻抗模拟的工作原理

智能电网线路阻抗模拟是一种通过模拟电网线路的阻抗特性来实现电网故障检测和定位的技术。智能电网系统通过安装在电网线路上的传感器&#xff0c;实时采集线路上的电流、电压等参数&#xff0c;并将这些数据传输到监控中心。监控中心接收到传感器采集的数据后&#xff0c;对数…

Java排序算法之贪心算法

贪心算法是一种优化问题的解决方法&#xff0c;它在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最优的。贪心算法常用于最优化问题&#xff0c;比如最小生成树、哈夫曼编码、最短路径等。贪心算法是一…

《ThingsBoard从入门到精通》的优秀课程

0、介绍 多年java物联网行业开发&#xff0c;精通物联网平台的架构与设计&#xff0c;精通开源物联网平台ThingsBoard&#xff0c;ThingsBoard专家。最近出了一套《ThingsBoard从入门到精通》的全套课程&#xff0c;只要学习了这一套课程&#xff0c;你将随便驾驭ThingsBoard。…

.net core windows 最详细步骤,傻瓜式如何安装rabbitmq 通知消息中间件

本次安装环境信息&#xff1a; 系统&#xff1a;win11 64位专业版 erlang rabbitMQ 一、下载安装程序 rabbitMQ安装程序下载路径&#xff1a;Installing on Windows — RabbitMQ 不能下载使用 Index of /download/ (erlang.org) otp_win64_22.0.exe

Qt图形视图框架:QGraphicsItem详解

Qt图形视图框架&#xff1a;QGraphicsItem详解 Chapter1 Qt图形视图框架&#xff1a;QGraphicsItem详解Chapter2 自定义QGraphicsItem实现平移、改变尺寸和旋转1. 平移2. 改变尺寸3. 旋转完整代码如下&#xff1a;头文件源文件 Chapter1 Qt图形视图框架&#xff1a;QGraphicsIt…

docker部署Prometheus+Cadvisor+Grafana实现服务器监控

一&#xff1a;Prometheus 1&#xff1a;介绍&#xff1a; Prometheus是一个在SoundCloud上构建的开源系统监视和警报工具包 2&#xff1a;特点 多维度数据模型-由指标键值对标识的时间序列数据组成&#xff1b;PromQL&#xff0c;一种灵活的查询语言&#xff1b;不依赖分布…

前端JS解构数组对象

// 3. 对象数组解构const arr [{username: 小明,age: 18,agw:19},{username: 小ha,age: 18,agw:19}]arr.map(item>item.age)//js结构数组对象console.log( arr.map(item>{return {aaa:item.age,bbb:item.username}}))

【Proteus仿真】【Arduino单片机】DHT11温湿度

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、DHT11温湿度传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器采集温度和湿度。 二、软件设…

基于JAVA SpringBoot和HTML美食网站博客程序设计

摘要 美食网站是一个提供各种美食信息和食谱的网站&#xff0c;旨在帮助用户发现、学习和分享美食。旨在探讨美食网站在现代社会中的重要性和影响。随着互联网的普及&#xff0c;越来越多的人开始使用美食网站来获取各种美食信息和食谱。这些网站不仅提供了方便快捷的搜索功能&…

Live800:客服中心必备的7种客户服务原则

在现代商业社会中&#xff0c;客户服务已经成为企业竞争的重要因素之一。提供高质量的客户服务可以帮助企业赢得客户的忠诚度和信任&#xff0c;从而推动企业的发展。客服中心是企业与客户之间的桥梁&#xff0c;对于客户服务的质量要求更高。为了提高客服中心的服务质量&#…

冰点还原精灵Deep Freeze for mac:Mac用户的最佳系统保护选择

你是否曾在Mac上安装软件后&#xff0c;发现系统性能下降&#xff0c;或者某些应用程序无法正常运行&#xff1f;这些问题可能让你感到困扰&#xff0c;但幸运的是&#xff0c;有一个解决方案可以帮你解决这些问题——Faronics Deep Freeze for mac。 Deep Freeze for mac是一…

【fbtft】如何添加fbtft驱动

获取lcd ic的datasheet&#xff0c;或者直接找到其他平台&#xff08;linux&#xff0c;stm32&#xff0c;esp32&#xff09;的驱动 我用的是合宙的esp32驱动&#xff0c;注意是c语言的&#xff0c;合宙上层用lua封装了&#xff0c;需要找到sdk源码。 源码路径&#xff1a; …

解决Python中使用requests库遇到的身份验证错误

在使用requests库进行HTTP请求时&#xff0c;用户遇到了一个AuthenticationRequired&#xff08;身份验证必须&#xff09;的错误。然而&#xff0c;当使用urllib.request.urlopen执行相同的操作时&#xff0c;却能够成功。同时&#xff0c;用户提供了自己的系统信息&#xff0…

哔哩哔哩自动引流软件的运行分享,以及涉及到技术与核心代码分享

先来看实操成果&#xff0c;↑↑需要的同学可看我名字↖↖↖↖↖&#xff0c;或评论888无偿分享 大家好&#xff0c;我是一名专注于自动引流软件研发的技术专家。今天&#xff0c;我将与大家分享自动引流软件涉及到的技术与核心代码&#xff0c;希望能为大家提供一些有价值的参…

论文笔记——BiFormer

Title: BiFormer: Vision Transformer with Bi-Level Routing AttentionPaper: https://arxiv.org/pdf/2303.08810.pdfCode: https://github.com/rayleizhu/BiFormer 一、前言 众所周知&#xff0c;Transformer相比于CNNs的一大核心优势便是借助自注意力机制的优势捕捉长距离…

Kohana框架的安装及部署

Kohana框架的安装及部署 tipsKohana安装以及部署1、重要文件作用说明1.1 /index.php1.2 /application/bootstrap.php 2、项目结构3、路由配置3.1、隐藏项目入口的路由3.2、配置默认路由3.3、配置自定义的路由(Controller目录下的控制器)3.4、配置自定义的路由(Controller/direc…

java排序算法之桶排序

图解 桶排序&#xff08;Bucket sort&#xff09;是一个排序算法&#xff0c;它的主要思想是将需要排序的数据分到有限数量的桶里。每个桶里的数据再进行单独的排序&#xff0c;最后按照顺序将每个桶里的数据依次取出&#xff0c;即可完成排序。 桶排序的具体实现可以分为以下几…