文件操作中的IO流——字节流与字符流

news2024/11/20 4:22:20

一,IO流

1.什么是IO流

IO流是存取和读取数据的解决方案

2.IO流的作用

IO流用于读写数据,这些数据包括本地文件和网络上的一些数据;比如读写本地文件的时候需要用到文件读写的IO流,读写网络上的数据时需要通过Socket套接字来调用数据流来进行网络数据的读写

3.IO流的分类

如何判断一个文件是不是纯文本文件:可以将该文件用记事本的方式打开,观察其是不是乱码,如果是乱码说明该文件不是纯文本文件,否则就是!!!

分别以word文件和txt文件举例(分别在文件中保存一段文字“我爱中国”):

word

word文件用记事本打开是乱码,所以不是纯文本文件

txt:

txt文件用记事本打开显示“我爱中国”,所以是纯文本文件

二,字节流(InputStream/OutputStream)

1.字节输出流(OutputStream)

输出流指的是往内存上写入数据,每次写的时候按照字节为单位进行书写;

OutputStream是一个抽象类,在实例化对象时需要使用向上转型,采用子类FileOutputStram(这里主要是操作文件)来创建对象。

OutputStream相关方法

修饰符及返回值类型

方法签名

说明

void

write(int b)

写入一个整数,在文件中显示对应ASCII对应的字符

void

write(byte[] b)

写入一个字节数组

int

write(byte[] b,int off,int len)

写入对应条件长度的字节数组

void

close()

关闭字节流

void

flush()

刷新缓冲区

OutputStream中最重要的方法是write,write方法有三种形式,分别进行代码演示,在进行代码示例之前我们需要知道字节流写数据时的相关细节:

字节流写数据
1.如果文件不存在会自动创建一个文件,但是要保证父亲路径存在
2.如果文件存在会先清空文件,否则需要在实例化OutputStream对象时另加一个参数设置为true(该参数的意思是支持续写)
3.write方法的三种用法
1) write(int b):写入一个整数,但是存储的ASCII值,所以也可以直接写一个字符,字符也是一个整数
2)write(byte[] b):写入一个字节数组,所以用字节流想要写入字符串的时候需要将字符串先转换成字节数组
3)write(byte[] b, int off, int len):将字符数组从off下标开始写len个长度的数据元素
/**
* 在当前项目的路径下创建一个a.txt文件
*/
public static void main(String[] args) throws IOException {
        //创建对象
        OutputStream outputStream = new FileOutputStream("./a.txt");
        //写数据
        //1.写入一个整数,文件中存储的是ASCII值
        outputStream.write(97);
        outputStream.write(98);
        //2.写入一个字节数组或者字符串,如果写入的是字符串的话也需要转换成字节数组
        byte[] bytes = {97, 98, 99, 100};
        outputStream.write(bytes);
        String str1 = "abc";
        outputStream.write(str1.getBytes());
        //3.写入一个字符数组,从off下标开始写len个长度的数据元素
        String str2 = "abc";
        outputStream.write(str2.getBytes(), 0, 3);

        //关闭资源
        outputStream.close();
    }

第一种写法:写入一个整数,文件中存储的是ASCII值

第二种写法:写入一个字节数组或者字符串,如果写入的是字符串的话也需要转换成字节数组

第三种写法:写入一个字符数组,从off下标开始写len个长度的数据元素

2.字节输入流(InputStream)

输入流指的是从内存上读取数据,每次读取的时候按照字节为单位进行读取;

InputStream是一个抽象类,在实例化对象时需要使用向上转型,采用子类FileInputStream(这里主要是操作文件)来创建对象。

InputStream相关方法

修饰符及返回值类型

方法签名

说明

int

read()

读取一个字节的数据

int

read(byte[] b)

最多读取b.length子节点额数据到b中,返回实际读到的数量

int

read(byte[] b,int off,int len)

最多读取len-off字节的数据到b中,放在从off开始,返回实际读到的数量

int

close()

关闭字节流

InputStream中最重要的方法是readread方法有三种形式,这里主要讲解前两种,在进行代码示例之前我们需要知道字节流读取数据时的相关细节:

字节流读数据
1.如果文件不存在会直接报错,和输出流写数据区分开
2.read方法
read():一次读取一个字节
1)一次读一个字节,返回的是该数据在ASCII表上所对应的数字,如果想返回字符本身需要强转成char类型
2)当读取的数据很多时,需要循环读取的时候,判断此时读到的数据是不是-1即可,否则就继续读
read(byte[] b):一次读取多个字节
当读取的文件很大,一次读取一个字节很费事的时候,可以采用一次读取多个字节
设置一个缓存数组,一般数组创建的越大,拷贝速度越快(但是数组创建的太大会占用内存资源),所以一般设置成1024的整数倍
/**
* 读取当前项目的路径下的一个a.txt文件,假设存储的是abc
*/
public static void main(String[] args) throws IOException {
        //创建对象
        InputStream inputStream = new FileInputStream("./a.txt");

        //读取数据
        //1.一个字节一个字节的读
        int a = inputStream.read();
        System.out.println((char) a);
        //2.循环读取
        int b = 0;//变量b一定要定义
        while ((b = inputStream.read()) != -1) {
            System.out.print((char) b);
        }
        //3.一次读取多个字节,用缓存数组
        byte[] bytes = new byte[2];//一次读取多少个字节和数组的长度有关
        int len = 0;
        while ((len = inputStream.read(bytes)) != -1) {
            //每次读取之后会替换之前的字节数组
            //注意这里一定要写读取的数组的长度,因为可能某一次读取的长度不足数组的长度,所以只需要读len的长度即可
            System.out.println(new String(bytes, 0, len));
        }

        //关闭资源
        inputStream.close();
    }

第一种读取方法:一个字节一个字节的读

第二种方法:循环读取

第三种方法:一次读取多个字节,用缓存数组

    • 单个字节和多个字节效率区别(使用拷贝文件的案例演示)

假设有一个照片的路径为:C:/Users/14611/Videos/Captures/a.png,大小为:6,866,962 字节;
需要拷贝到路径为:D:/b.png下并命名为b.png
观察单个字节拷贝和多个字节拷贝下的效率区别!

单子字节:

public static void main(String[] args) throws IOException {
        //创建对象,需要创建两个对象
        //输入流:用来读取文件
        //输出流:用来将读取到的数据写入文件中
        InputStream inputStream = new FileInputStream("C:/Users/14611/Videos/Captures/a.png");
        OutputStream outputStream = new FileOutputStream("D:/b.png");

        //进行拷贝
        long beg = System.currentTimeMillis();
        int b = 0;
        while ((b = inputStream.read()) != -1) {
            outputStream.write(b);
        }
        long end = System.currentTimeMillis();
        //关闭资源(先创建的流最后关闭)
        outputStream.close();
        inputStream.close();
        System.out.println("拷贝花费时间为:" + (end - beg) + "ms");
    }

多个字节:

public static void main(String[] args) throws IOException {
        //创建对象,需要创建两个对象
        //输入流:用来读取文件
        //输出流:用来将读取到的数据写入文件中
        InputStream inputStream = new FileInputStream("C:/Users/14611/Videos/Captures/a.png");
        OutputStream outputStream = new FileOutputStream("D:/c.png");

        //进行拷贝
        long beg = System.currentTimeMillis();
        byte[] bytes = new byte[1024 * 1024 * 5];
        int len = 0;
        while ((len = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, len);//写的时候要设置长度,不能把整个数组都读
        }
        long end = System.currentTimeMillis();
        //关闭资源(先创建的流最后关闭)
        outputStream.close();
        inputStream.close();
        System.out.println("拷贝花费时间为:" + (end - beg) + "ms");
    }

两个方法均可以完全拷贝出相同的照片文件,但是每次读取写入多个字节的方法的时间效率明显由于单个字节的方法!

三,字符流(Reader/Write)

    • 字符输入流(Reader)

字符输入流在进读取数据的时候,每次都是读取一个字节,遇到中文时,GBK编码读两个字节,读UTF-8编码读三个字节

Reader相关方法

修饰符及返回值类型

方法签名

说明

int

read()

读取一个数据

int

read(char[] buffer)

读取多个数据

void

close()

关闭字符流

Reader中最重要的方法是readread方法有两种形式,这里主要讲解前两种,在进行代码示例之前我们需要知道字符流读取数据时的相关细节:

字符流读数据,底层就是字节流
输入流:一次读一个字节,遇到中文时,一次就会读取多个字节
输出流:底层会把数据按照指定的编码方式进行编码,变成字节再写到文件中
适用于纯文本文件进行读写操作
1.如果文件不存在,会直接报错
2.read方法:方法读取完之后会自动解码并转成十进制,所以读取汉字的时候需要强转
read():按字节进行读取,遇到中文,一次读多个字节,读取后解码,返回一个整数(GBK一次读两个字节,UTF-8一次读三个字节)
read(char[] buffer):一次读取多个并放到字符数组中
/**
* 读取当前项目的路径下的一个a.txt文件,假设存储的是abc我爱中国
*/
public static void main(String[] args) throws IOException {
        //创建对象
        Reader reader = new FileReader("./a.txt");

        //读取数据
        //1.无参的read方法
        int ch = 0;
        while ((ch = reader.read()) != -1) {
            System.out.println(ch);
        }
        //2.有参的read方法
        char[] chars = new char[2];//表示一次读两个数据
        int len = 0;
        int count = 0;
        while ((len = reader.read(chars)) != -1) {
            count++;
            //把数组的数据变成字符串再进行打印
            System.out.println(new String(chars, 0, len));
            System.out.println(count);
        }

        //关闭资源
        reader.close();
    }

第一种方法:无参的read方法

第二种方法:有参的read方法(每次读两个数据并换行)

2.字符输出流(Writer)

字符输出流在进写数据的时候,每次都是写入一个字节,遇到中文时,GBK编码写入两个字节,读UTF-8编码写入三个字节

Writer相关方法

Writer也有类似的几种写数据的方法,但是用的最多的就是写入字符串(只需了解这一种用法即可

write方法的相关细节:

字符流写数据
1.文件不存在会创建一个新的路径,但是要保证父亲路径存在
2.如果文件已经存在,则会清空文件,如果不想清空需要打开续写开关,即设置成true即可
3.如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符

用的最多的方法是写一个字符串
/**
* 在当前项目的路径下创建一个a.txt文件
*/
public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("./a.txt");
        writer.write("你好中国");//是12个字节
        writer.close();
    }

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

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

相关文章

机器学习:公式推导与代码实现-监督学习单模型

线性回归 线性回归(linear regression)是线性模型的一种典型方法。 回归分析不再局限于线性回归这一具体模型和算法,更包含了广泛的由自变量到因变量的机器学习建模思想。 原理推导 线性回归学习的关键问题在于确定参数w和b,使得拟合输出y与真实输出yi尽可能接近 为了求…

PowerDesigner16.5配置安装与使用

PowerDesigner16.5百度云下载链接 链接:https://pan.baidu.com/s/1b9XUqxVZ8gTqk_9grptcAQ?pwd3pl7 提取码:3pl7 一:软件安装 1.下载安装包(包含安装文件、汉化包、注册文件) 2.下载后文件内容如下 3.进入安装文件中…

5. 统计学基础1:平均值...四分位数、方差、标准差(均方差)、标准误(标准误差、均方根误差)、 标准分

文章目录1. 平均值、中位数、众数、极差、四分位数(即下、中、上四份位数)2. 方差(Var、D(X) 、σ^2^)、标准差【也叫均方差】(SD 、σ)3. 标准误【也叫标准误差、均方根误差】(SE)4…

高空探测数据处理--对流层顶选取

对流层的概念(维基百科) 对流层(英语:Troposphere)是地球大气层中最靠近地面的一层,也是地球大气层里密度最高的一层。它蕴含了整个大气层约75%的质量,以及几乎所有的水蒸气及气溶胶。 对流层从地球表面开始向高空伸展,直至对流层顶,即平流层的起点为止。对流层的上…

【Labview】每日一题

🚩write in front🚩 🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5&#xff5…

The ATIS Spoken Language Systems Pilot Corpus

摘要 语音研究有巨大的进步在过去使用以下的模式: 定义研究问题收集语料针对性的衡量进展解决这个研究问题 自然语言研究,另一方面,取得了典型的进步在没有任何数据语料的情况下,这能够测试研究的假设。 我们描述了ATISATISATIS试点语料库…

从C到C++及类与对象

目录 从C到C 嵌入式领域常用的GUI 语法的升级 引用 默认参数 函数重载 堆内存 概念和思维的升级 类和对象 类的申明 类的成员函数 常成员、常对象(C推荐const而不用#define, mutable ) 静态成员(属于类不属于对象) 友元(破坏…

Opencv实战案例——模板匹配实现银行卡号识别(附详细介绍及完整代码下载地址)

Opencv目录1.项目意义2.模板匹配3.图像二值化3.1全局阈值3.2全局阈值代码即效果展示3.3 自适应阈值3.4自适应阈值代码即效果展示4.轮廓筛选4.1轮廓检测4.2绘制轮廓4.3轮廓筛选代码及效果展示5.形态学变化5.1腐蚀5.2膨胀5.3开运算和闭运算、礼帽和黑帽6.项目实战6.1读取图片转化…

next_permutation函数讲解

目录 前言: 简要概述: 例题(1): P1088 [NOIP2004 普及组] 火星人 题目描述 输入格式 输出格式 输入输出样例 说明/提示 代码(1): 例题(2)&#xf…

如何开发 Vite 3 插件构建 Electron 开发环境?(文末附视频讲解)

开发新版本 Vue 项目推荐你使用 Vite 脚手架构建开发环境,然而 Vite 脚手架更倾向于构建纯 Web 页面,而不是桌面应用,因此开发者要做很多额外的配置和开发工作才能把 Electron 引入到 Vue 项目中,这也是很多开发者都基于开源工具来…

用户多兴趣建模MIND

1. 概述 在工业界,一个完整的推荐系统中通常包括两个阶段,分别为召回阶段和排序阶段。在召回阶段,根据用户的兴趣从海量的商品中去检索出用户(User)可能感兴趣的候选商品( Item),满…

JavaEE进阶第二课:Spring创建与使用

上一篇我们介绍了Spring的概念,知道了Spring是众多工具方法的IoC容器。 但是纸上谈兵终觉浅,这一篇文章就来介绍Spring创建与使用, 注之后我们对对象的称呼就叫Bean 1.1Spring项目的创建与配置 1.创建maven项目,语言选java&…

【1819. 序列中不同最大公约数的数目】

来源:力扣(LeetCode) 描述: 给你一个由正整数组成的数组 nums 。 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数。 例如,序列 [4,6,16] 的最大公约数是 2 。 数组的一个 子序列 本质是一个序…

Python(16):Numpy之array数组的数值计算

目录 0. 相关文章链接 1. 创建Array数组 2. 基本数值计算 2.1. numpy中的函数 2.2. 数组中的函数 3. 指定维度进行计算 3.1. numpy中的函数 3.2. 数组中的函数 4. 复杂计算 4.1. 统计乘机 4.2. 获取对应值的索引位置 4.3. 求平均值 4.4. 求标准差 4.5. 求方差 4…

【MFEN:轻量级多尺度特征提取:SR网络】

MFEN: Lightweight multi-scale feature extraction super-resolution network in embedded system (MFEN:嵌入式轻量级多尺度特征提取超分辨率网络) 深度卷积神经网络(CNN)在超分辨率(SR)方面…

基于java springboot+mybatis爱游旅行平台前台+后台设计实现

基于java springbootmybatis爱游旅行平台前台后台设计实现 博主介绍:5年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获…

PCI、PCI-X、PCI-E、PCI-E Card、Mini PCI-E、M.2、Add-in Card 这些概念你搞清楚了吗

搞硬件或通信的“攻城狮”们,免不了要和各种通信协议及接口打交道。比如,我们经常接触PCI、PCI-X、PCI-E、PCI-E Card、Mini PCI-E、M.2(NGFF)、Add-in Card这些概念,作为“攻城狮”队伍中的一员,你搞清楚它们之间的关系了吗&…

Linux第一个小程序-进度条

目录 \r&&\n 行缓冲区概念 倒计时程序 进度条代码 \r&&\n 回车概念换行概念 \n[rootVM-12-17-centos lesson8]# touch test.c [rootVM-12-17-centos lesson8]# touoch Makefile bash: touoch: command not found [rootVM-12-17-centos lesson8]# touch Mak…

Python:每日一题之完全二叉树的权值

题目描述 给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是 A1​,A2​,⋅⋅⋅AN​,如下图所示: 现在小张要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权…

【Linux操作系统】Linux进程状态和两个特殊进程

文章目录一.一套普适性的进程状态理论1.运行2.阻塞3.挂起二.一套具体的Linux进程状态1.R-运行2.S-睡眠3.T-暂停5.t-被追踪三.僵尸进程和孤儿进程1.僵尸进程2.孤儿进程一.一套普适性的进程状态理论 1.运行 由于CPU数量相对于进程数量来说少之又少,所以CPU维护了一个运行队列,方…