java IO流(二) 字符流 缓冲流

news2024/11/16 1:28:21

请添加图片描述

字符流

前面学习的字节流虽然可以读取文件中的字节数据,但是如果文件中有中文,使用字节流来读取,就有可能读到半个汉字的情况,这样会导致乱码。虽然使用读取全部字节的方法不会出现乱码,但是如果文件过大又不太合适。
所以Java专门提供了另外一种流,叫字符流,字符流是专门为读取文本数据而生的。

FileReader类 读取字符
FileReader读取文件的步骤如下:

第一步:创建FileReader对象与要读取的源文件接通
第二步:调用read()方法读取文件中的字符
第三步:调用close()方法关闭流

请添加图片描述

public class FileReaderTest1 {
    public static void main(String[] args)  {
        try (
                // 1、创建一个文件字符输入流管道与源文件接通
                Reader fr = new FileReader("io-app2\\src\\01.txt");
                ){
            // 2、一个字符一个字符的读(性能较差)
//            int c; // 记住每次读取的字符编号。
//            while ((c = fr.read()) != -1){
//                System.out.print((char) c);
//            }
            // 每次读取一个字符的形式,性能肯定是比较差的。

            // 3、每次读取多个字符。(性能是比较不错的!)
            char[] buffer = new char[3];
            int len; // 记住每次读取了多少个字符。
            while ((len = fr.read(buffer)) != -1){
                // 读取多少倒出多少
                System.out.print(new String(buffer, 0, len));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

FileWriter类 写字符
FileWriter往文件中写字符数据的步骤如下:

第一步:创建FileWirter对象与要读取的目标文件接通
第二步:调用write(字符数据/字符数组/字符串)方法读取文件中的字符
第三步:调用close()方法关闭流

请添加图片描述

public class FileWriterTest2 {
    public static void main(String[] args) {
        try (
                // 0、创建一个文件字符输出流管道与目标文件接通。
                // 覆盖管道
                // Writer fw = new FileWriter("io-app2/src/02out.txt");
                // 追加数据的管道
                Writer fw = new FileWriter("io-app2/src/02out.txt", true);
                ){
            // 1、public void write(int c):写一个字符出去
            fw.write('a');
            fw.write(97);//写了个a
            //fw.write('磊'); // 写一个字符出去
            fw.write("\r\n"); // 换行符 win平台是\n 但是\r\n能兼容更多平台

            // 2、public void write(String c)写一个字符串出去
            fw.write("我爱你中国abc");
            fw.write("\r\n");

            // 3、public void write(String c ,int pos ,int len):写字符串的一部分出去
            fw.write("我爱你中国abc", 0, 5);
            fw.write("\r\n");

            // 4、public void write(char[] buffer):写一个字符数组出去
            char[] buffer = {'黑', '马', 'a', 'b', 'c'};
            fw.write(buffer);
            fw.write("\r\n");

            // 5、public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
            fw.write(buffer, 0, 2);
            fw.write("\r\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这里有一个小问题,FileWriter写完数据之后,必须刷新或者关闭,写出去的数据才能生效。
比如:下面的代码只调用了写数据的方法,没有关流的方法。当你打开目标文件时,是看不到任何数据的。

//1.创建FileWriter对象
Writer fw = new FileWriter("io-app2/src/03out.txt");

//2.写字符数据出去
fw.write('a');
fw.write('b');
fw.write('c');

而下面的代码,加上了flush()方法之后,数据就会立即到目标文件中去。

//1.创建FileWriter对象
Writer fw = new FileWriter("io-app2/src/03out.txt");

//2.写字符数据出去
fw.write('a');
fw.write('b');
fw.write('c');

//3.刷新
fw.flush(); 

下面的代码,调用了close()方法,数据也会立即到文件中去。因为close()方法在关闭流之前,会将内存中缓存的数据先刷新到文件,再关流。

//1.创建FileWriter对象
Writer fw = new FileWriter("io-app2/src/03out.txt");

//2.写字符数据出去
fw.write('a');
fw.write('b');
fw.write('c');

//3.关闭流
fw.close(); //会先刷新,再关流

但是需要注意的是,关闭流之后,就不能在对流进行操作了。否则会出异常


缓冲流

请添加图片描述

缓冲流有四种,如上图所示.缓冲流的作用:可以对原始流进行包装,提高原始流读写数据的性能。

字节缓冲流
其是在缓冲流的底层自己封装了一个长度为8KB(8129byte)的字节数组,但是缓冲流不能单独使用,它需要依赖于原始流。
读数据时它先用原始字节输入流一次性读取8KB的数据存入缓冲流内部的数组中,再从8KB的字节数组中读取一个字节或者多个字节。
写数据时 它是先把数据写到缓冲流内部的8BK的数组中,等数组存满了,再通过原始的字节输出流,一次性写到目标文件中去。

请添加图片描述

请添加图片描述

在创建缓冲字节流对象时,需要封装一个原始流对象进来。构造方法如下

请添加图片描述

PS:构造函数第二个参数可以指定字节数组大小,默认为8k。

如果我们用缓冲流复制文件,代码写法如下:

public class BufferedInputStreamTest1 {
    public static void main(String[] args) {
        try (
                InputStream is = new FileInputStream("io-app2/src/01.txt");
                // 1、定义一个字节缓冲输入流包装原始的字节输入流
                InputStream bis = new BufferedInputStream(is);

                OutputStream os = new FileOutputStream("io-app2/src/01_bak.txt");
                // 2、定义一个字节缓冲输出流包装原始的字节输出流
                OutputStream bos = new BufferedOutputStream(os);
        ){

            byte[] buffer = new byte[1024];
            int len;
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer, 0, len);
            }
            System.out.println("复制完成!!");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

字符缓冲流
它的原理和字节缓冲流是类似的,它底层也会有一个8KB的数组,但是这里是字符数组。字符缓冲流也不能单独使用,它需要依赖于原始字符流一起使用。构造方法如下

请添加图片描述

请添加图片描述

BufferedReader还有新增的方法,一次可以读取文本文件中的一行:

请添加图片描述

BufferedWriter还有新增的方法,可以用来写一个换行符:

请添加图片描述

使用BufferedReader读取数据的代码如下

public class BufferedReaderTest2 {
    public static void main(String[] args)  {
        try (
                Reader fr = new FileReader("io-app2\\src\\04.txt");
                // 创建一个字符缓冲输入流包装原始的字符输入流
                BufferedReader br = new BufferedReader(fr);
        ){
//            char[] buffer = new char[3];
//            int len;
//            while ((len = br.read(buffer)) != -1){
//                System.out.print(new String(buffer, 0, len));
//            }
//            System.out.println(br.readLine());
//            System.out.println(br.readLine());
//            System.out.println(br.readLine());
//            System.out.println(br.readLine());

            String line; // 记住每次读取的一行数据
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

使用BufferedWriter往文件中写入字符数据

public class BufferedWriterTest3 {
    public static void main(String[] args) {
        try (
                Writer fw = new FileWriter("io-app2/src/05out.txt", true);
                // 创建一个字符缓冲输出流管道包装原始的字符输出流
                BufferedWriter bw = new BufferedWriter(fw);
        ){

            bw.write('a');
            bw.write(97);
            bw.write('磊');
            bw.newLine();

            bw.write("我爱你中国abc");
            bw.newLine();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

缓冲流性能分析
我们说缓冲流内部多了一个数组,可以提高原始流的读写性能。它和我们使用原始流,自己加一个8BK数组不是一样的吗? 缓冲流就一定能提高性能吗?结论:缓冲流不一定能提高性能。缓冲流的性能不一定比低级流高,其实低级流自己加一个数组,性能其实是不差。只不过缓冲流帮你加了一个相对而言大小比较合理的数组 。

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

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

相关文章

Docker常用命令以及详解

Docker常用命令以及详解 一、基础命令: docker version 功能:显示 docker 客户端和服务器的版本信息。docker info 功能:显示 docker 系统的详细信息docker --help 功能:显示 Docker 命令的帮助信息。示例输出:这个…

聚焦!智慧燃气使用体验到底怎么样?

文章来源:网络 关键词:智慧燃气、智能管网、智能气网、智慧燃气系统、智慧燃气平台 随着科技的发展,物联网技术不断进步,智能燃气也时常出现在我们的生活中。但大多数人仍然对智慧燃气知之甚少。究竟何为智慧燃气?能…

无涯教程-JavaScript - DVAR函数

描述 DVAR函数使用与指定条件相匹配的列表或数据库的列中的数字,根据样本估算总体的方差。 语法 DVAR (database, field, criteria)争论 Argument描述Required/Optionaldatabase 组成列表或数据库的单元格范围。 数据库是相关数据的列表,其中相关信息的行是记录,数据的列是…

Kruise Rollout:基于 Lua 脚本的可扩展流量调度方案

作者:潘梦源 前言 Kruise Rollout [ 1] 是 OpenKruise 社区开源的渐进式交付框架。Kruise Rollout 支持配合流量和实例灰度的金丝雀发布、蓝绿发布、A/B Testing 发布,以及发布过程能够基于 Prometheus Metrics 指标自动化分批与暂停,并提供…

【B树 B+树】B树、B+树理论

目录 引入B树B树定义和性质m阶B树核心特性 B树B树的查找 引入B树 满足上面两个策略就是B树: m 叉查找树中,规定除了根节点外,任何结点至少有 ⌈ m / 2 ⌉ \lceil m/2 \rceil ⌈m/2⌉ 个分叉,即至少含有 ⌈ m / 2 ⌉ \lceil m/2 \…

【Linux网络编程】环境配置篇

由于博主本学期所使用的Linux系统为Ubuntu,所以这篇博客会先以安装虚拟机和Ubuntu开始。 虚拟机的话,可以选择VMware,也可以选择VirtualBox。直接选择安装就行,这个应该是没有什么问题的。但是,如果之前电脑安装过Vmwa…

器件介绍TPS25821DSSR、TPS65994ADRSLR USB Type-C接口IC,TPS65982DMCZBHR坞站管理控制器

一、TPS25821 USB Type-C™ 电源控制器和 1.5A 电源开关 概述:TPS25820/21 是一款 USB Type-C 电源控制器,集成了一个额定电流为 1.5A 的 USB 电源开关。TPS25820/21 通过监测 Type-C 配置通道 (CC) 线路来确定 USB 接收装置是否连接。如果连接了接收装…

python基础运用例子

python基础运用例子 1、⼀⾏代码交换 a , b :a, b b, a2、⼀⾏代码反转列表 l[::-1]3、合并两个字典 res {**dict1, **dict2}**操作符合并两个字典for循环合并dict(a, **b) 的方式dict(a.items() b.items()) 的方式dict.update(other_dict) 的方式 4、⼀⾏代码列…

使用Pyspider进行API接口抓取和数据采集

API接口是一种常见的数据获取方式,它可以提供文本格式的数据,并且具有高度的实时性和可靠性。而Pyspider是一个基于Python的强大的网络爬虫框架,它提供了丰富的功能和灵活的扩展性,使我们可以轻松地进行数据的抓取和处理。在我们的…

深度学习环境搭建笔记(二):mmdetection-CPU安装和训练

文章目录 第一步:安装anaconda第二步:安装虚拟环境第三步:安装torch和torchvision第四步: 安装mmcv-full第五步: 安装mmdetection第六步:测试环境第七步:训练-目标检测7.1 准备数据集7.2 检查数据集7.3 训练网络 第一步…

数据库-多表查询

概述: 介绍:多表查询:指从多张表中查询数据 笛卡儿积:笛卡儿积是指在数学中,两个集合(A集合和B集合)的所有组合情况(在多表查询时,需要消除无效的笛卡儿积) 分…

7. read_excel()函数读取Excel文件

【目录】 文章目录 1. pandas库读取数据2. read_excel()函数读取Excel文件3. 准备工作4. 路径前的r是什么5. io参数 绝对路径6. io 相对路径7. sheet_name:要读取的sheet的名称或索引7.1 sheet_name参数 名字7.2 sheet_name参数 顺序 8. index_col参数指定行索引…

[译]这8个CSS小技巧,你知道吗?

前言 在网页设计和前端开发中,CSS属性是非常重要的一部分。掌握常用的CSS属性不仅可以使你的网页看起来更美观,还能提升用户体验,今天小编为大家介绍8个常见的CSS小技巧: 1.修改滚动条样式 下图是我们常见的滚动条,…

开发前期准备工作

开发前期准备工作 文章目录 开发前期准备工作0 代码规范0.1 强制0.2 推荐0.3 参考dao:跟数据库打交道service:业务层,人类思维解决controller:抽象化 0.4 注释规范0.5 日志规范0.6 专有名词0.7 控制层统一异常统一结构体控制层提示…

2023年8月CSDN客服月报|解决个3重大问题和8个次要问题,处理个用户需求及建议

听用户心声,解用户之需。hello,大家好,这里是《CSDN客诉报告》第23期,接下来就请大家一同回顾我们8月份解决的bug~ 一、重大问题 1、【主站】博客访问异常 反馈量:102 持续时间:7月31日15:4…

Xcode,swift:Error Domain=kCLErrorDomain Code=1 (null)问题解决

问题描述: iOS开发时,当使用用户的位置权限时,获取用户经纬度报错:Error DomainkCLErrorDomain Code1 "(null)",错误域kCLError域代码1“(null)” 解决方法: 打开模拟机的设置-通用-语言与地区 将地区设置为中国(如果你的开发位置在中国的话) 点击左上方Features,选择…

leetCode动态规划“不同路径II”

迷宫问题是比较经典的算法问题,一般可以用动态规划、回溯等方法进行解题,这道题目是我昨晚不同路径这道题趁热打铁继续做的,思路与原题差不多,只是有需要注意细节的地方,那么话不多说,直接上coding和解析&a…

[Linux]编写一个极简版的shell(版本1)

[Linux]编写一个极简版的shell-version1 文章目录 [Linux]编写一个极简版的shell-version1命令行提示符打印接收命令行参数将命令行参数进行解释执行用户命令完整代码 本文能够帮助Linux系统学习者通过代码的角度更好地理解命令行解释器的实现原理。 命令行提示符打印 Linux操…

将两个文件夹中重复的图象删除

将两个文件夹中重复的图象删除 需求分析解决方案 需求分析 文件夹one和two存在图象的重复,将two文件中中重复的文件夹删除 解决方案 # coding: utf-8 from PIL import Image, ImageDraw, ImageFont import os import shutil import cv2 as cv import numpy as np …

二分搜索树节点的插入(Java 实例代码)

目录 二分搜索树节点的插入 Java 实例代码 src/runoob/binary/BinarySearchTreeInsert.java 文件代码&#xff1a; 二分搜索树节点的插入 首先定义一个二分搜索树&#xff0c;Java 代码表示如下: public class BST<Key extends Comparable<Key>, Value> { …