java--io流(一)

news2025/1/15 23:59:06

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.coloradmin.cn/o/1653885.html

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

相关文章

Baidu Comate智能编码助手 -----AI编程帮你解放双手

目录 Baidu Comate是什么&#xff1f; Baidu Comate如何安装&#xff1f; 在VSCode上安装Baidu Comate插件 Baidu Comate如何使用&#xff0c;有哪些功能&#xff1f; 1.代码解释 2.代码注释 使用感受 如何体验 Baidu Comate是什么&#xff1f; Baidu Comate智能编码助手…

Comate,一款基于文心大模型的智能编程助手

一、官网 Baidu Comate官网 二、安装VSCode 如何下载安装VSCode 三、VSCode安装Comate 安装方式1 访问Comate官网点击 立即安装Comate插件 按钮快速安装 安装方式2 访问VSCode市场中的BaiduComate 点击 Install 按钮访问扩展详情界面 2.打开VSCode 3.安装Comate 四、…

图像降噪算法 NL-means 介绍

介绍 Non-Local Means 非局部均值降噪算法&#xff0c;简称NLM&#xff0c;该算法来自 2005年论文“A non-local algorithm for image denoising”&#xff1b;该算法是经典的图像降噪算法&#xff0c;是很多降噪算法的参考对比算法。 2014 年&#xff0c;有 NLM衍生算法NLMP…

树莓派4b测量PM2.5

1.GP2Y1010AU0F粉尘传感器连接图 2. GP2Y1010AU0F工作原理 工作原理 传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。 3.源代码 main.py # coding=UTF-8 import RPi.GPIO as GPIO from ADC import ADS1015…

正点原子i.MX 93开发板,双核A55+M33+NPU,双路RS485FDCAN千兆网,异核/AI/工业开发!

正点原子i.MX 93开发板新品上市&#xff01;双核A55M33NPU&#xff0c;双路RS485&FDCAN&千兆网&#xff0c;异核/AI/工业开发&#xff01; NXP的i.MX系列是一系列面向多媒体和工业应用的ARM架构微处理器。从i.MX6U到i.MX93&#xff0c;这一系列经历了显著的发展&#x…

kubectl_进阶_安全

安全 在前面的学习中&#xff0c;我们知道对于资源对象的操作都是通过 APIServer 进行的&#xff0c;那么集群是怎样知道我们的请求就是合法的请求呢&#xff1f; 这就涉及到k8s的安全相关的知识了。 1. API对象 Kubernetes有一个很基本的特性就是它的所有资源对象都是模型…

TypeScript 基础学习笔记:interface 与 type 的异同

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 TypeScript 学习笔记&#xff1a;interface 与 type 的异同&#x1f3a3; 引言&#x1f680; 快速入门1️⃣ Interface&#xff08;接口&#xff09;&#x1f4cb; 定义&#x1f91d; 实现&#x1f4a1; 特点 2️⃣ Type Al…

深度学习网络:设计、开发和部署

​书籍&#xff1a;Deep Learning Networks: Design, Development and Deployment 作者&#xff1a;Jayakumar Singaram&#xff0c;S. S. Iyengar&#xff0c;Azad M. Madni 出版&#xff1a;Springer书籍下载-《​深度学习网络&#xff1a;设计、开发和部署》该教材为学生和工…

Redis 实战之RDB文件结构

RDB文件结构 databases 部分key_value_pairs 部分value 的编码字符串对象列表对象集合对象哈希表对象有序集合对象INTSET 编码的集合ZIPLIST 编码的列表、哈希表或者有序集合 总结AOF持久化的实现命令追加 AOF 文件的写入与同步小结 在本章之前的内容中&#xff0c; 我们介绍了…

后门通信模型剖析

通信模型剖析 梳理DinodasRAT Linux后门通信模型如下&#xff1a; 发送数据-通信数据结构 #原始数据 20000000e703881435b674f7de23a2f80fe35ac0ba1a46c7d96e08a8747889eacf6b1950#载荷数据 e703881435b674f7de23a2f80fe35ac0ba1a46c7d96e08a8747889eacf6b1950#数据解密 180…

Datasophon基于dinky1.0.1升级到dinky1.0.2

1.首先下载dinky1.0.2版本 dinky1.0.2下载地址 2.关闭dinky1.0.1 3.升级dinky1.0.2 3.1 解压dinky1.0.2.ta.gz tar -xzvf dinky-release-1.16-1.0.2.tar.gz -C /opt/datasophon/rm -rf dinky-release-1.16-1.0.2.tar.gz复制dinky1.0.1的配置文件到dinky1.0.2目录 cp /op…

leetcode91.解码方法(动态规划)

问题描述&#xff1a; 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> "2" ... Z -> "26" 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可…

难定取舍,静观其变

今&#xff08;2024年5月8日&#xff09;天&#xff0c;本“人民体验官”在推广人民日报官方微博文化产品《带着笑意的眼睛&#xff0c;能看见最美的风景》的同时&#xff0c;还要联系4月初至今期间&#xff0c;与隐藏在《麻辣论坛》幕后的那位昵称“800727”者所爆发的一连串&…

Python:一种强大的编程语言与无限可能

引言 Python是一种易于学习且功能强大的编程语言&#xff0c;它被广泛用于各种领域&#xff0c;包括数据科学、人工智能、Web开发、系统自动化等。Python以其简洁的语法、丰富的库和易于阅读的风格&#xff0c;成为了许多开发者的首选。本文将探讨Python的特性和应用&#xff…

用户下单操作

一&#xff1a;用户下单需求分析和设计&#xff1a; 用户下单业务说明&#xff1a; 在电商系统中&#xff0c;用户是通过下单的方式通知商家&#xff0c;用户已经购买了商品&#xff0c;需要商家进行备货和发货。 用户下单后会产生订单相关数据&#xff0c;订单数据需要能够体…

pytest教程-40-钩子函数-pytest_runtest_call

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_runtest_setup钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_runtest_call钩子函数的使用方法。 pytest_runtest_call 钩子函数在 pytest 调用测试函数&#xff08;即测试用…

探索 JavaScript 宇宙:DOM与BOM的星际邂逅

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 &#x1f4af;Web API&#x1f340;1 API的概念&#x1f340;2 Web API的概念…

JavaScript数字分隔符

● 如果现在我们用一个很大的数字&#xff0c;例如2300000000&#xff0c;这样真的不便于我们进行阅读&#xff0c;我们希望用千位分隔符来隔开它&#xff0c;例如230,000,000; ● 下面我们使用_当作分隔符来尝试一下 const diameter 287_266_000_000; console.log(diameter)…

xhs 旋转滑块流程分析

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 前言 之前搞过 x-s的纯…

CentOs9编译C指令报错的一种解决方案

今天使用centos9编译c代码时&#xff0c;显示bash: gcc: command not found... 下图是我的报错页面&#xff0c;依据提示信息安装gcc之后依旧显示失败 找到其中一种解决方式&#xff0c;完美解决&#xff0c;供参考 输入以下指令更新软件包列表&#xff0c;这里需要等待几分…