java--io流(一)

1. 前置知识

字符集是什么?

字符集(Character Set)是一组字符的集合,它定义了可以在计算机系统中使用的所有字符。字符集可以包括字母、数字、标点符号、控制字符、图形符号等。字符集使得计算机能够存储、处理和显示各种语言和符号。

字符集的分类:

一般认识这几种:ASCII(美国标准信息交换码),GBK(汉字内码扩展规范),Unicode(统一码,也叫万国码),UTF-8(使用广泛),UTF-16

理解字符集:

1.ASCII(美国标准信息交换码):包含128个字符,主要包括英文字母、数字和一些特殊字符,使用1个字节存储一个字符,首位是0。(2^7 = 128)

2.GBK(汉字内码扩展规范):包含两万多汉字,一个汉字编码为两个字节,同时兼容ASCII编码,汉字编码首位为1。

3.Unicode(统一码,也叫万国码):还有另外一种叫法(UTF-32),就是32位二进制数也就是4个字节表示一个字符,不管是汉字还是其他符号,过于奢侈(浪费内存)。

4.UTF-8(使用广泛):采取可变长编码方案,共分为4个长度区:字节长度1,2,3,4。英文、数字等只占用1个字节(兼容ASCII码),汉字占用3个字节:具体看下图:

字符集相关的方法及用法:

字符集的编码、解码操作:(java完成了对字符的编码和解码,String提供了以下方法:)

编码:

1.byte[] getBytes():使用平台默认字符集,将String编码为字节数组存储到新的字节数组中

2.byte[] getBytes(String charsetName):使用指定字符集,将String编码为字节数组存储到新的字节数组中

解码:(String的构造器)

1.String(byte[] bytes)

2.String(byte[] bytes,String charsetName)

以下是示例图:

2. io流

什么是io流?

 i就是input(叫做输入流)就是网络或者磁盘文件等中读取数据到程序中;o就是output(叫做输出流)就是将程序中的数据写入到网络或者磁盘文件等中。

io流的分类:

按照流向分:输入流、输出流

按照流中数据的最小单元分:字节流、字符流

大类:字节输入流,字节输出流,字符输入流,字符输出流

io流有什么用?

io流一般应用场景:

       记事本记事,游戏最高分存储,通信等

io流怎么用?

首先我们要知道四大类:字节输入流,字节输出流,字符输入流,字符输出流。他们其实都是抽象类,使用时需要使用其子类(实现类),下面将分别介绍两大类(字节输入输出流)的实现类及其用法:

3. FileInputStream实现类

使用步骤:

1.创建输入流管道(对象),建立与源文件的连接(构造器中写文件路径【绝对/相对】)

2.以字节形式从文件中读取数据read()方法返回编码(可以转换类型为显而易见的类型);可以使用while循环读取大量字节

注意事项:

1.不能读取汉字,会出现乱码现象(read()只读取一个字节,在UTF-8中汉字占3个字节)

2.读取数据的性能太差

3.任何流的使用后都要关闭流,调用close方法

import java.io.FileInputStream;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
       //完成 FileInputStream实现类 的 1)使用流程 2)检查read() 和 read(byte[] buffer)的注意事项:关于汉字是否可以读取
        //1.FileInputStream实现类是InputStream类的一个实现类,具体是字节输入流,以字节的形式从磁盘或网络上读取数据到程序中;
        //read()具体的使用步骤如下:
            //1)第一步:建立程序和源文件(获取源)的管道,也就是创建FileInputStream实现类的一个对象;
            //2)第二步:用对象调用read()方法,得到数据的编码,每次只能得到一个字节的数据;
            //3)第三步:关闭流;
        FileInputStream is = new FileInputStream("hellomodule\\src\\com\\yym\\test\\yjwj.txt");
        //后面的路径可以是:绝对路径、相对路径(当前工作目录下的)

        //一个一个字节读入;
//        int ch = is.read();
//        int ch1 = is.read();
//        int ch2 = is.read();
//        System.out.print((char)ch);
//        System.out.print((char)ch1);
//        System.out.print((char)ch2);


//        int b;
//        while((b = is.read()) != -1){
//            System.out.print((char)b);
//        }

        //2.使用read(byte[] buffer)
            //1.第一步:建立程序和源文件(获取源)的管道,也就是创建FileInputStream实现类的一个对象;
            //2.准备byte[] buffer的大小;
            //3.is调用read(byte[] buffer),得到大量的编码,并返回读取的字节数;
        byte[] buffer = new byte[6];

        //读取一次读取5个字节到字节数组中;
//        int len = is.read(buffer);

//        for (int i = 0; i < buffer.length; i++) {
//            System.out.print((char)buffer[i]);
//        }
//        System.out.println();

        //for循环可以改变为String类型;
        //String rs = new String(buffer);

//        System.out.println(len);

        int len;
        while((len = is.read(buffer))!=-1){
            //String rs = new String(buffer);
            String rs = new String(buffer,0,len);
            System.out.println(rs);
            System.out.println(len);
        }
        //但是现在有一个问题是覆盖之后,会将之前读到的字节保留并一并读出,现在的目的是:想要读多少字节就倒出多少字节;
        //只需要使用String的另外一个构造器:String rs = new String(buffer,0,len);

        //3.关于能不能读汉字问题:首先read()不可以读汉字,read(byte[] buffer)可以读入汉字,但是要保证一个汉字读入的字节数为3
        //所以有一个问题:在英文汉字都有的而且字数不确定的文章中,无法保证读入的正确性;除非已知文件字节数大小,一次性读出。
        //因此:会有字符输入流解决相关问题;
        is.close();
    }
}

 对于在英文汉字都有的而且字数不确定的文章中,无法保证读入的正确性的问题,有以下两种解决措施:

 方法一:

 方法一中,size作为参数时需要强制转换为int,原因如下:

byte数组的定义中,大小不能超过int类型,size的类型是一个long类型,直接用会报错,所以要强制转换。一般文件不会特别大,因此可以用这样的代码;但是有100GB大小的文件,然而,内存只有32GB甚至更小,这样就不能new出一个字节很大的byte数组来一次读取文件。

 方法二:直接替换定义size开始的四行代码(更方便,但是仍然没有解决文件过大时的读取问题)

 

4. FileOutputStream实现类

使用步骤:

1.创建输入流管道(对象),建立与源文件的连接(构造器中写文件路径【绝对/相对】)

2.以字节形式从文件中读取数据:read(byte[] buffer)方法得到编码(可以转换类型为显而易见的类型);返回读取的字节数量

注意事项:

1.不能读取汉字,会出现乱码现象(read()只读取一个字节,在UTF-8中汉字占3个字节)

2.读取数据的性能太差

3.任何流的使用后都要关闭流,调用close方法

注意事项:

1.读取多少,倒多少(buffer数组可以多次使用,但是非首次使用时会覆盖前面位置的数据,为了防止后面出现bug,非首次读取定长后一定要倒出)eg:文件内容:abc66 ,buffer大小为3 ,第一次读取:【a,b,c】,第二次读取:【6,6,c】。其实第二次读了2个字节,应该倒出2个字节的数据【6,6】.

2每次读取完毕返回-1

使用流程几乎相同,只有划红线部分:如果是true,那么就支持向文件中追加,不然默认是false,就是先清空再写入。

注意

1.在new出一个输出流管道时,可以直接跟一个不存在的路径,会自动创建文件。

2.write方法可以写入任何内容文件,在前后文件结构相同的情况下不出现乱码。

原因:

1.write方法可以写入任何类型的字节数据,因为它本质上不关心数据的语义或结构——它只负责将字节序列写入到输出目的地。

2.字节输出流是字节为中心的,它不涉及字符编码转换。无论你传递给它的是文本数据、

图片视频还是其他任何二进制文件,他都会写入这些字节

5. 文件复制demo

字节流适合做数据的转移,如:文件复制等

使用字节输入输出流进行文件复制,适用于任何文件:
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Main {
    public static void main(String[] args) throws Exception {

        //目的:完成复制文件的操作;这里举例一张图片的复制;
        //基本思路:
        //1.字节输入流连通源文件
        //2.字节输出流连通目标文件
        //3.将读入的字节放到字节数组中,再写入到目标文件中

        FileInputStream is = new FileInputStream("C:\\Users\\11067\\Pictures\\Screenshots\\屏幕截图 2023-10-20 175018.png");
        FileOutputStream os = new FileOutputStream("D:\\学习文档\\屏幕截图 2023-10-20 175018.png");

        //1.不管文件多大,直接用数组装
//        byte[] buffer = new byte[3];
//        int len;
//        while((len = is.read(buffer)) != -1){
//            os.write(buffer,0,len);
//        }
//        System.out.println("复制完成!");
        //2.直接用readAllBytes
        byte[] buffer = is.readAllBytes();
        os.write(buffer);
        System.out.println("复制完成!");

        os.close();
        is.close();
    }
}

6. 释放资源的方式

 最初,我们会手动的用close方法释放资源对象,但是如果在释放前程序异常终止,那么资源就得不到释放,已知占用内存,此时就提出了:try-catch-finally(用于捕获异常,并且不论是否有异常,程序都可以执行finally区去释放资源对象,除非JVM终止),如:

这是一段核心代码,可见他的结构臃肿,不方便。因此,我们又提出了 try-with-resouces,使用框架:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

idea 项目 修改项目文件名 教程

文章目录 目录 文章目录 修改流程 小结 概要流程技术细节小结 概要 原项目名 修改流程 关掉当前项目的idea页面 修改之后的文件名 重新打开idea。选择项目打开项目页面 技术细节 出现下面这个问题&#xff0c;可以参考作者新的一编文章idea开发工具 项目使用Spring框架开发解…

【智能楼宇秘籍】一网关多协议无缝对接BACnet+OPC+MQTT

在繁华的都市中心&#xff0c;一座崭新的大型商业综合体拔地而起&#xff0c;集购物、餐饮、娱乐、办公于一体&#xff0c;是现代城市生活的缩影。然而&#xff0c;这座综合体的幕后英雄——一套高度集成的楼宇自动化系统&#xff0c;正是依靠多功能协议网关&#xff0c;实现了…

《从零开始,搭建一个简单的UVM验证平台》实操

最近的工作中需要用UVM平台去仿真软件同事写的C程序&#xff0c;虽然只要用EDA同事已经搭好的UVM平台稍微改改就行&#xff0c;但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的&#xff0c;因为我对这方面一点概念都没有。 基于此&…

一文盘点 Partisia Blockchain 生态 4 月市场进展

Partisia Blockchain 是一个以高迸发、隐私、高度可互操作性、可拓展为特性的 Layer1 网络。通过将 MPC 技术方案引入到区块链系统中&#xff0c;以零知识证明&#xff08;ZK&#xff09;技术和多方计算&#xff08;MPC&#xff09;为基础&#xff0c;共同保障在不影响网络完整…

redis--安装

简介 官网&#xff1a;RedisInsight - The Best Redis GUI 各个版本官网下载地址&#xff1a;http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库&#xff0c;MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…

17.接口自动化学习-日志

1.日志输出渠道 &#xff08;1&#xff09;文件格式 xx.log &#xff08;2&#xff09;控制台输出 2.日志级别 debug<info<warnning<error<critical 3.代码实现 from utils.handle_path import log_path import logging import datetime def logger(fileLogTr…

rocketMQ-常用知识点

1、RocketMQ有什么作用&#xff1f; 1、应用解耦 系统的耦合性越高&#xff0c;容错性就越低。以电商应用为例&#xff0c;用户创建订单后&#xff0c;如果耦合调用库存系统、物流系统、支付系统&#xff0c;任何一个子系统出了故障或者因为升级等原因暂时不可用&#xff0c;都…

多线程【阻塞队列】(生产者消费者模型代码实现)

阻塞队列 解耦合削峰填谷生产者消费者模型&#xff1a; 解耦合 削峰填谷 生产者消费者模型&#xff1a; 正常来说&#xff0c;wait通过notify唤醒&#xff0c;其他线程调用了take,在take的最后一步进行notify. package thread; class MyBlockingQueue{private String [] data…

OpenCV 入门(二)—— 车牌定位

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

存储虚拟化概述

目录 1. 存储体系架构 2. 存储设备层虚拟化 3. 块聚合层虚拟化 3.1. 块聚合层虚拟化实现方式 3.2. 块聚合层虚拟化分类 3.3. 块聚合层虚拟化技术 4. 文件/记录层的存储虚拟化 存储虚拟化是一种将存储系统的内部功能从应用、主机或者网络资源中抽象、隐藏或者隔离的技术&…

事业单位向媒体投稿发文章上级领导交给了我投稿方法

作为一名事业单位的普通职员,负责信息宣传工作,我见证了从传统投稿方式到智能化转型的全过程,这段旅程既是一次挑战,也是一次宝贵的成长。回想起初涉此领域的日子,那些通过邮箱投稿的时光,至今仍然历历在目,其中的酸甜苦辣,构成了我职业生涯中一段难忘的经历。 邮箱投稿:费时费…

06-beanFactoryPostProcessor的执行

文章目录 invokeBeanFactoryPostProcessors(beanFactory)invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);invokeBeanFactoryPostProcessors(regularPostProc…

JAVA基础之jsp标准标签

jsp动作标签实现实例化一个实体类 <jsp:useBean id"标识符" class"java类名" scope"作用范围"> 传统的java方式实例化一个实体类 Users user new Users(); <%%> id: 对象名 * class:类 创建对象时,完全限定名(包名…

设置默认表空间和重命名

目录 设置默认表空间 创建的临时表空间 tspace4 修改为默认临时表空间 创建的永久性表空间 tspace3 修改为默认永久表空间 重命名表空间 将表空间 tspace3 修改为 tspace3_1 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/13520…

Spring Boot | Spring Boot 整合 “RabbitMQ“ ( 消息中间件 ) 实现

目录: Spring Boot 整合 "RabbitMQ" ( 消息中间件 )实现 &#xff1a;一、Spring Boot 整合 整合实现 : Publish/Subscribe ( 发布订阅 ) 工作模式 ( "3种"整合实现方式 )1.1 基于"API"的方式 ( 实现 Publish/Subscribe "发布订阅"工作…

OSPF Stub区域

原理概述 OSPF 协议定义了多种区域&#xff08; Area &#xff09;类型&#xff0c;其中比较常见的有 Stub 区域和 Totally Stub 区域。区域的类型决定了在这个区域当中所存在的 LSA 的类型。 Stub 区域不允许 Type-4和 Type-5 LSA 进入&#xff0c;该区域会通过 Type-3 LSA…

电子商务对应的职业有哪些?10年互联网人透底行业秘密!

电子商务对应的职业有哪些&#xff1f;10年互联网人透底行业秘密&#xff01; 事实说话&#xff0c;实事求是&#xff0c;不要再把美颜滤镜下的市场&#xff0c;传给新人小伙伴了&#xff01; 大家好&#xff0c;我是微三云胡佳东&#xff0c;一家软件公司负责人&#xff01; …

keystone学习小结

1 keystone middleware 1.1 工作流程 middleware在客户端和服务端之间&#xff0c;会拦截客户端请求并判断请求身份是否是正确合法的&#xff0c;若是&#xff0c;则继续将请求发给其他middleware或app 具体看&#xff0c;干了这些事 1将请求里的auth header去除&#xff0c…

景源畅信:想要做抖音电商有哪些适合的发展渠道?

在数字浪潮的推动下&#xff0c;抖音电商如同一股不可阻挡的潮流&#xff0c;正吸引着无数创业者和品牌的目光。如何在这一领域获得成功&#xff0c;选择合适的发展渠道成为关键。接下来&#xff0c;让我们深入探讨这一话题&#xff0c;揭开抖音电商成功之路的秘密。 一、内容创…

C# Web控件与数据感应之 TreeView 类

目录 关于 TreeView 一些区别 准备数据源 范例运行环境 一些实用方法 获取数据进行呈现 ​根据ID设置节点 获取所有结点的索引 小结 关于 TreeView 数据感应也即数据捆绑&#xff0c;是一种动态的&#xff0c;Web控件与数据源之间的交互&#xff0c;本文将继续介绍与…
最新文章