【IO流中的字节流(InputStream)(OutputStream)】

news2024/11/17 13:22:27

字符集


美国人发明计算机
要将他们的字符存入计算机(英文字母、数字、标点、特殊字符)
给字符进行编号,组成了一张ASCII码表(美国信息交换标准代码),一共包含128个字符
该码表以1个字节存储1个字符,首位都是0

中文的字符存不下
所以我们推出了GBK(汉字内码扩展规范,国标)
该码表以2个字节存储1个字符,包含了2万多个汉字字符
GBK兼容了ASCII,但是规定汉字的首位是1

各个国家都推出自己的字符集
国际组织制定了Unicode万国码,它可以容纳世界上所有的文字、符号
Unicode最初的编码方式为UTF-32,统一以4个字节存储1个字符,这样存储的弊端是占用存储空间且通信效率低
所以后来流行了UTF-8编码方式,它采取可变长编码方案
英文字符、数字等只占1个字节,且兼容标准ASCII编码,汉字字符占用3个字节

注意
Windows里的ANSI其实是Windows code pages,这个模式根据当前locale选定具体的编码
比如简体中文locale下是GBK,在ASCII范围内是和ASCII一致的
 

编码

UTF-8
是Unicode字符集的一种编码方案,采取可变长编码方案,总共分为四个长度区(1到4个字节)
由于兼容ASCII码表,所以英文、数字只占1个字节,汉字占3个字节
UTF-8是我们实际开发最常见的码表

UTF-8编码方案(二进制)
0xxxxxxx(ASCII码)
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

重点记忆
ASCII字符集: 只有英文、数字、符号等,占1个字节
GBK字符集:汉字占2个字节,英文、数字、符号等占1个字节
UTF-8编码方案:汉字占3个字节,英文、数字、符号等占1个字节

注意事项
编码时使用的字符集,和解码时使用的字符集必须一致,否则可能出现乱码
英文、数字一般不会乱码,因为很多字符集都兼容了ASCII编码
 

String提供了如下方法

说明

byte[] getBytes()

使用平台默认的字符集将该String编码为一系列字节,将结果存储到新的字节数组中

byte[] getBytes(String charsetName)

使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中 

解码

String提供了如下方法

说明

String(byte[] bytes)

通过平台默认的字符集,解码指定的字节数组来构造新的String

String(byte[] bytes, String charsetName)

通过指定的字符集,解码指定的字节数组来构造新的String

 如何使用Java程序对字符进行编码?

String类的方法 byte[] getBytes​():默认字符集编码

byte[] getBytes​(String charsetName):指定字符集编码

如何使用Java程序对字节进行解码?

String类的构造器 String​(byte[] bytes):使用默认字符集解码

String​(byte[] bytes, String charsetName):指定字符集解码

IO流

 

  • 字节输入流:以内存为基准,将来自磁盘文件、网络中的数据以字节的形式读入到内存中去的流
  • 字节输出流:以内存为基准,将内存中的数据以字节写出到磁盘文件或者网络中去的流
  • 字符输入流:以内存为基准,来自磁盘文件、网络中的数据以字符的形式读入到内存中去的流
  • 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络中去的流 

IO流的作用?

读、写文件数据的

IO流是怎么划分的,大体分为几类,各自的作用?

字节输入流 InputStream(读字节数据的) 字节输出流 OutoutStream(写字节数据出去的) 字符输入流 Reader(读字符数据的) 字符输出流 Writer(写字符数据出去的) 

FileInputStream(字节输入流)

构造器

说明

   public FileInputStream​(File file)

创建字节输入流管道与源文件接通

   public FileInputStream​(String pathname)(常用底层封装了new File)

创建字节输入流管道与源文件接通

 

方法名称 

说明

   public int read()

每次读取一个字节返回,如果发现没有数据可读会返回-1.

   public int read(byte[] buffer)

每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1

 

public class Demo {
    public static void main(String[] args) throws Exception {
        //1、创建字节输入流,关联文件
        FileInputStream fis = new FileInputStream("day09\\Demo06.txt");

        //2、循环读,读到文件末尾(-1)停止
        int b;
        while ((b = fis.read()) != -1) {
            System.out.print((char) b); //abcdecfé»é©¬ 中文现乱码
        }

        //3、释放资源
        fis.close();
    }
}

使用FileInputStream每次读取一个字节,读取性能较差,并且读取汉字输出会乱码

文件字节输入流的作用是什么?

将数据以字节的形式读取到内存

每次读取一个字节的方法是哪个?

public int read();

每次读取一个字节存在什么问题?

读取性能较差,每次读取一个字节都需要和硬盘交互 将中文拆分读取,必定乱码 流使用完需要关闭(释放资源),否则占用资源别人就不能用了

public class Demo {
    public static void main(String[] args) throws Exception {
        //创建字节输入流对象,关联文件
        FileInputStream fis = new FileInputStream("day09\\Demo07.txt");

        //一次读多个字节(使用数组一次读多个)
        byte[] bytes = new byte[3];

        //public int read(byte[] buffer); 用字节数组读数据,返回读取到的有效字节个数,读到文件末尾(没读到有效内容)会返回-1
        int len = fis.read(bytes);
        System.out.println("本次读取到的有效字节个数:" + len);
        System.out.println(new String(bytes, 0, len));

        int len2 = fis.read(bytes);
        System.out.println("本次读取到的有效字节个数:" + len2);
        System.out.println(new String(bytes, 0, len2));

        //释放资源
        fis.close();
    }
}

使用FileInputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码

文件字节输入流:一次读取完全部字节

方法名称

说明

public byte[] readAllBytes() throws IOException

直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回

   */
        //创建流对象,关联文件
        FileInputStream fis = new FileInputStream("day09\\Demo09.txt");
        //一次性读完所有字节
        byte[] bytes = fis.readAllBytes(); //注意:如果文件过大(数组长度 > Integer.MAX_VALUE),底层或抛异常
        //展示数据
        System.out.println(new String(bytes));

 

如何使用字节输入流读取中文内容输出时不乱码呢?

一次性读取完全部字节 可以定义与文件一样大的字节数组读取,也可以使用官方API 直接把文件数据全部读取到一个字节数组可以避免乱码,

是否存在问题?

如果文件过大,定义的字节数组可能引起内存溢出 

FileOutputStream(文件字节输出流)

作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去

构造器

说明

public FileOutputStream​(File file)

创建字节输出流管道与源文件对象接通

public FileOutputStream​(String filepath)

创建字节输出流管道与源文件路径接通

public FileOutputStream​(File file,boolean append)

创建字节输出流管道与源文件对象接通,可追加数据

public FileOutputStream​(String filepath,boolean append)

创建字节输出流管道与源文件路径接通,可追加数据

方法名称

说明

public void write(int a)

写一个字节出去

public void write(byte[] buffer)

写一个字节数组出去

public void write(byte[] buffer , int pos , int len)

写一个字节数组的一部分出去

public void close() throws IOException

关闭流

 如何创建字节输出流管道,如何实现写数据的追加操作?

public FileOutputStream(String pathname); 在构造第二个参数传递true,默认为false表示不追加

字节输出流写数据的方法有哪些?

public void write(int a); 写一个字节

public void write(byte[] bytes); 写一个字节数组

public void write(byte[] bytes, int pos, int len);

写一个字节数组的一部分 字节输出流如何实现写出去的数据可以换行?

如果要写换行,需要写“\r\n”的字节数组表示形式

public class Demo {
    public static void main(String[] args) throws Exception {
        //public FileOutputStream(String pathname); 创建字节输出流关联文件,文件不存在则创建,存在则清空内容
        OutputStream os = new FileOutputStream("day09\\Demo10.txt", true);

        //public void write(int a); 写一个字节
        os.write(65);
        os.write(66);
        os.write(67);

        //注意1、如果要写换行,需要写"\r\n"的字节数组表示形式
        os.write("\r\n".getBytes());

        //public void write(byte[] bytes); 写一个字节数组
        byte[] bytes = {48, 49, 50, 51, 52};
        os.write(bytes);
        os.write("\r\n".getBytes());

        //public void write(byte[] bytes, int pos, int len); 写一个字节数组的一部分
        //需求:写出字节数组最后三个字节
        os.write(bytes, 2, 3);
        os.write("\r\n".getBytes());

        //释放资源
        os.close();
    }
}

 文件的复制

     任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,只要复制后的文件格式一致就没问题!

public class Demo02 {
    public static void main(String[] args)throws Exception {
        FileInputStream fis = new FileInputStream("E:\\Demo09.txt");
        FileOutputStream os = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\copy.txt");
        //边读边写:一次读写一个字节
/*        int b;
        while ((b=fis.read())!=-1){
                os.write(b);
        }*/
        //边读编写,一次读取多个;
        int len;
        byte[] bytes = new byte[1024 * 3];
        while ((len = fis.read(bytes))!=-1){
            os.write(bytes,0,len);
        }


    }
}

try-catch-finally

finally特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止

作用:用于在程序执行完成后进行资源的释放操作(专业级做法) 

package com.demo12_IO流_释放资源1;

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

/*
    try-catch-finally
        finally代码块写在try-catch的最后面
        无论try中程序是否正常正式,最后一定会执行finally中的代码,除非JVM终止
        注意不要在finally代码块中返回结果,会扰乱运行结果

    finally代码块作用
        目前多用于释放资源
 */

// TODO: 能够说出 IO流资源释放的方式有哪些

public class Demo {
    public static void main(String[] args) {
        //method();
        //System.out.println(getSum(10, 20)); //错误结果100

        /*
            需求:捕获下面代码中的异常,并正确的释放资源
         */

        //提升作用域
        InputStream is = null;
        try {
            //在这里出现了异常,直接进入catch环节,后面的代码就不会执行了
            System.out.println(10 / 0);

            is = new FileInputStream("day09\\Demo05.txt");
            System.out.println(is.read());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            try {
                if (is != null) {
                    //is有可能是null,所以加上非空判断(如果is是null,没有必要做释放资源)
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static int getSum(int a, int b) {
        try {
            return a + b;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //注意不要在finally代码块中返回结果,会扰乱运行结果
            return 100;
        }
    }

    public static void method() {
        try {
            //无论try中程序是否正常正式,最后一定会执行finally中的代码,除非JVM终止
            System.out.println(10 / 0); //数学运算异常
        } catch (Exception e) {
            e.printStackTrace();
        } finally { //finally代码块写在try-catch的最后面
            System.out.println("finally..");
        }
    }
}

try-with-resource

该资源使用完毕后,会自动调用其close()方法,完成对资源的释放

  • 小括号()中只能放置资源,否则报错;
  • 资源指的是最终实现了AutoCloseable接口.
package com.demo13_IO流_释放资源2;
/*
    try-with-resource
        JDK7开始提供的释放资源方式,编码更简洁
        try后面小括号中只能定义资源对象,最终底层会帮我们释放这些对象
        资源指实现了AutoCloseable接口的对象

        Closeable是AutoCloseable的子接口
            public interface Closeable extends AutoCloseable {
                public void close() throws IOException;
                ..
            }

    书写格式
        try(要释放的资源对象1, 资源对象2..){

        }catch(Exception e){
            处理异常的代码
        }
 */

// TODO: 能够说出 IO流资源释放的方式有哪些

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Random;
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        /*
            需求:捕获下面代码中的异常,并正确的释放资源
         */

        try (
                //定义资源(字节输入流)
                InputStream is = new FileInputStream("day09\\Demo05.txt");
                ) {
            //业务逻辑
            System.out.println(is.read());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

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

相关文章

Java 实现 国密SM4/ECB/PKCS7Padding对称加密解密

Java 实现 国密SM4/ECB/PKCS7Padding对称加密解密&#xff0c;为了演示方便本问使用的是IntelliJ IDEA 2022.1 (Community Edition)来构建代码的 1、pom.xml文件添加需要的jar <?xml version"1.0" encoding"UTF-8"?> <project xmlns"htt…

1002 Business

要解这道题目&#xff0c;感觉最关键的因素就是找到第 件任务最晚开始的时间 。这个看似简单&#xff0c;但是对建模的功底要求相当高。我一开始就把 当成了 &#xff0c;但其实不是的。后者就相当于把第 件任务锁死在最后面完成&#xff0c;但其实是允许放在之前完成的&am…

springboot2+redis 订阅发布,解决接收消息累计线程到内存溢出,使用自定义线程池接收消息

pom 添加redis <!-- redis 缓存操作 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> 发布消息 import lombok.extern.slf4j.Slf4j; import o…

FPGA原理与结构——FIFO IP核原理学习

一、FIFO概述 1、FIFO的定义 FIFO是英文First-In-First-Out的缩写&#xff0c;是一种先入先出的数据缓冲器&#xff0c;与一般的存储器的区别在于没有地址线&#xff0c; 使用起来简单&#xff0c;缺点是只能顺序读写数据&#xff0c;其数据地址由内部读写指针自动加1完成&…

DC电源模块关于输入电压范围

BOSHIDA DC电源模块关于输入电压范围 DC电源模块是一种常用的电源供应设备&#xff0c;其主要作用是将交流电转化为直流电&#xff0c;以供电子设备使用。在DC电源模块的使用过程中&#xff0c;输入电压范围是一个非常重要的参数&#xff0c;它关系到模块的稳定性、可靠性以及…

driver‘s license exam 1

驾考科目1&#xff0c;都是做题目 driver‘s license exam 1_spencer_tseng的博客-CSDN博客 driver‘s license exam 2_spencer_tseng的博客-CSDN博客 driver‘s license exam 3_spencer_tseng的博客-CSDN博客 driver‘s license exam 4_spencer_tseng的博客-CSDN博客 car …

对1GHz脉冲多普勒雷达进行快速和慢速处理生成5个移动目标的距离多普勒图研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

微信公众号关注/取消订阅事件一文详解

一、背景介绍 这周期的项目需求中需要做一个引导用户关注微信公众号的功能&#xff0c;但是引导用户关注的前提是需要实时获取当前用户是否已经关注微信公众号,如果光看官方文档还是对于一些小伙伴来说比较无从下手&#xff0c;所以我来分享以下我做的过程中遇到的问题以及解决…

Ansible 创建分区

实例&#xff1a; 创建一个名为/home/greg/ansible/partition.yml 的剧本&#xff0c;它在所有托管节点上运行&#xff0c;执行以下操作&#xff1a; 在设备 VDB 上创建大小为 1500 MB 的单个主分区 1 使用 ext4 文件系统格式化分区 在/n…

无涯教程-PHP - 性能优化

根据Zend小组的说明,以下插图显示了PHP 7与PHP 5.6和基于流行的基于PHP的应用程序上的HHVM 3.7。 Magento 1.9 与执行Magento事务的PHP 5.6相比&#xff0c;PHP 7的运行速度证明是其两倍。 Drupal 7 在执行Drupal事务时&#xff0c;与PHP 5.6相比&#xff0c;PHP 7的运行速度…

【Gitee提交pr】

Gitee提交pr 什么是pr怎样提交一个pr嘞&#xff1f; 什么是pr pr:指的是将自己的修改从自己的账号仓库dev下提交到官方账号仓库master下&#xff1b; 通俗来讲就是Gitee线上有属于自己的分支&#xff0c;然后本地在自己地分支修改完代码之后&#xff0c;提交到自己的线上分支&a…

十一、hadoop应用

1.上传数据集 27.19.74.143,2015/3/30 17:38,/static/image/common/faq.gif 110.52.250.126,2015/3/30 17:38,/data/cache/style_1_widthauto.css?y7a 27.19.74.143,2015/3/30 17:38,/static/image/common/hot_1.gif 27.19.74.143,2015/3/30 17:38,/static/image/common/hot_2…

【ESP32】启动电流不足——调试问题记录

【ESP32】启动电流不足——调试问题记录 本文主要记录基于esp32 自开发设备硬件调试过程&#xff0c;解决供电不足的问题&#xff0c;用于新手小白记录 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是喜欢记录零碎知识点的小菜鸟。&#x…

善于打仗的人,创造高势能,行动节奏恰当

善于打仗的人&#xff0c;创造高势能&#xff0c;行动节奏恰当 【安志强趣讲《孙子兵法》第18讲】 【原文】 激水之疾&#xff0c;至于漂石者&#xff0c;势也&#xff1b;鸷鸟之疾&#xff0c;至于毁折者&#xff0c;节也。 【注释】 激&#xff0c;阻截水流 节&#xff0c;时…

SensorService中Binder案例

SensorService中Binder案例 1、FWK实际操作在Native层2、Native层中代码实现Bn/Bp端2.1 代码实现Bn端2.2 代码实现Bp端2.2.1 模板interface_cast android12-release 1、FWK实际操作在Native层 SensorService.java实际操作Native层SensorService.cpp&#xff1b;对应Bn服务端。 …

人机界面通过RJ45口无线连接多台PLC

人机界面是系统和用户之间进行交互和信息交换的媒介&#xff0c;它实现信息的内部形式与人类可以接受形式之间的转换。人机界面产品由硬件和软件两部分组成&#xff0c;硬件部分包括处理器、显示单元、输入单元、通讯接口、数据存贮单元等&#xff0c;HMI软件一般分为两部分&am…

Ensp+Wireshark+VirtualBox+WinPcap

软件下载 [名称]&#xff1a;Ensp及辅助程序 [大小]&#xff1a;830.65MB [语言]&#xff1a;Chinese [安装环境]&#xff1a;Win7/Win8/Win10 [下载链接]&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1KbypgxAGQy07ijSAj3SvsQ 提取码&#xff1a;ly88 软件介…

秋招算法面经集合 | 华为、百度、腾讯、美团等

面试锦囊之面经分享系列&#xff0c;持续更新中 欢迎后台回复"面试"加入讨论组交流噢 写在前面 秋招告一段落&#xff0c;整理文件的时候发现之前记录的面经问题&#xff0c;主要是秋招前期的一些面试&#xff0c;后期由于实习比较忙没花时间整理。希望自己的面经可…

文件/文件夹加密:Newsoftwares Folder Lock 7.9.0 Crack

Newsoftwares Folder Lock 7.9文件夹锁 版本7 防弹数据加密 - 在几秒钟内锁定文件夹 - 即时加密文件 - 密码保护 USB/外部驱动器 - 粉碎并永久删除文件等等...... 视窗 向量 受到数百万人的信赖 82,283,016次下载并且还在增加中... 什么为什么如何 奖项常问问题特征丢失登记感…

BaiqiSoft MstHtmlEditor for .NET Crack

BaiqiSoft MstHtmlEditor for .NET Crack BaiqiSoft MstHtmlEditor获取.NET for win表单被认为是一个可以被用户轻松灵活地集成到C#、VB.NET甚至WPF软件中的元素。负责编辑的控制器&#xff0c;用于.NET Win Forms的MstHtmlEditor&#xff0c;允许用户和开发人员&#xff0c;甚…