Java基础15

  • 第十五章 IO流(转换流 字符流 字符缓冲流 打印流)
    • 15.1 字符编码和字符集
      • 15.1.1 字符编码
      • 15.1.2 字符集
      • 15.1.3 String类getBytes()方法介绍
    • 15.2 转换流
      • 15.2.1 转换流OutputStreamWriter
      • 15.2.2 OutputStreamWriter常用方法
        • 构造方法
        • 写出数据方法
      • 15.2.3 转换流InputStreamReader
      • 15.2.4 InputStreamReader常用方法
        • 构造方法
        • 读取数据方法
    • 15.3 字符流便捷类
      • 15.3.1 概述
      • 15.3.2 FileWriter类
        • 构造方法
        • 写出数据
      • 15.3.3 FileReader类
        • 构造方法
        • 读取数据
    • 15.4 字符缓冲流
      • 15.4.1 构造方法
      • 15.4.2 特有方法
      • 15.4.3 newLine()方法写换行符
      • 15.4.4 readLine()读取文本行
      • 15.4.5 文本练习
        • 案例分析
    • 15.5 打印流
      • 15.5.1 概述
      • 15.5.2 PrintWriter类
  • 总结

第十五章 IO流(转换流 字符流 字符缓冲流 打印流)

15.1 字符编码和字符集

15.1.1 字符编码

计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本符号。反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。

编码: 字符转换为字节。

解码:字节转换为字符。

  • 字符编码 Character Encoding : 就是一套自然语言的字符与二进制数之间的对应规则。
    生活中的文字和计算机文字的对应关系 a–>97–>0110 0001

15.1.2 字符集

  • 字符集Charset:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。

计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。


可见,当指定了编码,它所对应的字符集自然就指定了,所以编码才是我们最终要关心的。

  • ASCLL字符集:

    • ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
    • 基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。
  • ISO-8859-1字符集:

    • 拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
    • ISO-8859-1使用单字节编码,兼容ASCII编码。
  • GBxxx字符集:

    • GB就是国标的意思,是为了显示中文而设计的一套字符集。
    • GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。
    • GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。
      • 中文版操作系统使用的编码表就是GBK。
      • 中文汉字在2312和GBK编码表中均为两个字节表示,第一个字节为负数,第二个字节可能是负数也可能是正数。
    • GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。尚未正式启用。
  • Unicode字符集 :

    • Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。
    • 它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码实现方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。
    • UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:
    1. 128个US-ASCII字符,只需一个字节编码。
    2. 拉丁文等字符,需要二个字节编码。
    3. 大部分常用字(含中文),使用三个字节编码。
    4. 其他极少使用的Unicode辅助字符,使用四字节编码。
    5. UTF-8是变长编码表,汉字在UTF-8中均为负数。

15.1.3 String类getBytes()方法介绍

  • byte[] getBytes() 使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。

    • 使用平台默认字符集,将字符串编码为字节数组。
    • 平台通常指的是操作系统平台,而中文版操作系统平台的默认字符集是GBK.
public static void main(String[] args){ byte[] bytes = "你".getBytes(); System.out.println(Arrays.toString(bytes)); }

以上程序的执行结果为:[-28, -67, -96],3个字节,而GBK字符集汉字占用2个字节,UTF-8字符集汉字占有3个字节。

原因:IDEA启动JVM的时候,添加了启动参数: java -Dfile.encoding=UTF-8,启动JVM的时候将默认的字符集设置为了UTF-8。

  • byte[] getBytes(String charsetName )使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
public static void main(String[] args)throws Exception{ byte[] bytes = "你".getBytes("UTF-8"); System.out.println(Arrays.toString(bytes)); bytes = "你".getBytes("GBK"); System.out.println(Arrays.toString(bytes)); /* bytes = "你".getBytes("UTF-16LE"); System.out.println(Arrays.toString(bytes)); bytes = "你".getBytes("UTF-16LE"); System.out.println(Arrays.toString(bytes)); */}

常用编码表: GBK和UTF-8。

15.2 转换流

15.2.1 转换流OutputStreamWriter

java.io.OutputStreamwriter 类,继承Writer类,他是字符输出流,用于操作文本文件。OutputStreamwriter是字符流通向字节流的桥梁(字符流转成字节流),使用指定的字符集将字符编码为字节。它的字符集可以由名称指
定,也可以接受平台的默认字符集。

15.2.2 OutputStreamWriter常用方法

构造方法

  • OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。
  • OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。

OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("out.txt"));
OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("out.txt") , "GBK");

写出数据方法

  • void write(int c) 写出单个字符。
  • void write(char[] ch) 写出字符数组。
  • void write(char[] ch,int off,int len) 写出字符数组一部分,开始索引和写出的个数。
  • void write(String s) 写入字符串。
  • void flush() 刷新该流的缓冲,字符流写数据会先写在内存中,刷新后才会到达目的文件。
public static void main(String[] args) throws IOException { // 定义文件路径 String FileName = "E:\\out.txt"; // 创建流对象,默认UTF8编码 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName)); // 写出数据 osw.write("你好"); // 保存为6个字节osw.flush(); osw.close(); // 定义文件路径 String FileName2 = "E:\\out2.txt"; // 创建流对象,指定GBK编码 OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK"); // 写出数据 osw2.write("你好");// 保存为4个字节 osw2.flush();osw2.close();}

15.2.3 转换流InputStreamReader

java.io.InputStreamReader 类,继承Reader类,他是字符输入流,只能操作文本文件,不能操作其他类型文件。InputStreamReader是字节流通向字符流的桥梁(字节流转成字符流),使用指定的字符集将字符编码为字
节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

15.2.4 InputStreamReader常用方法

构造方法

  • InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。
  • InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。
InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");

读取数据方法

  • int read()读取单个字符,读取到文件末尾时返回-1。
  • int read(char[] ch) 读取字符存储到数组中个,返回读取到的字符个数,读取到文件末尾时返回-1。
void main(String[] args) throws IOException { // 定义文件路径,文件为gbk编码 String FileName = "E:\\file_gbk.txt"; // 创建流对象,默认UTF8编码 InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName)); // 创建流对象,指定GBK编码 InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK"); // 定义变量,保存字符 int read;// 使用默认编码字符流读取,乱码 while ((read = isr.read()) != -1) { System.out.print((char)read); }isr.close(); // 使用指定编码字符流读取,正常解析 while ((read = isr2.read()) != -1) { System.out.print((char)read);// 大家好 }isr2.close(); }

15.3 字符流便捷类

15.3.1 概述

使用转换流进行文本文件的读写可以进行编码表的设置,但是我们经常使用的是平台默认的编码表进行文本文件操作的,因此可以选择字符流的便捷类来使用。

  • FileWriter继承OutputStreamWriter,使用平台默认编码表写出数据。
  • FileReader继承InputStreamReader,使用平台默认编码表读取数据。

15.3.2 FileWriter类

构造方法

  • FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
  • FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。

写出数据

public static void main(String[] args) throws IOException { // 使用文件名称创建流对象 FileWriter fw = new FileWriter("fw.txt"); //写出单个字符 fw.write(97); fw.flush(); //写出字符数组 char[] chs = "ABCDED".toCharArray(); fw.write(chs); fw.flush(); //写出字符数组的一部分,开始索引,写出个数 fw.write(chs,1,3); fw.flush(); //写出字符串fw.write("Zy"); fw.flush(); fw.close(); }

注意:字符串输出数据,必须要使用flush()方法,否则数据在内存中,不会到达指定文件,close()方法在关闭前也会进行刷新,推荐写一次刷新一次,避免内存占用过多。

15.3.3 FileReader类

构造方法

  • FileWriter(File file) : 创建一个新的 FileWriter,给定要读取的File对象。
  • FileWriter(String fileName) : 创建一个新的 FileWriter,给定要读取的文件的名称。

读取数据

public static void main(String[] args) throws IOException { // 使用文件名称创建流对象 FileReader fr = new FileReader("read.txt"); // 定义变量,保存有效字符个数 int len ;// 定义字符数组,作为装字符数据的容器 char[] cbuf = new char[2]; // 循环读取while ((len = fr.read(cbuf))!=-1) { System.out.println(new String(cbuf,0,len)); }// 关闭资源 fr.close(); }

15.4 字符缓冲流

15.4.1 构造方法

  • public BufferedReader(Reader in) :创建一个 新的缓冲输入流。
  • public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。
//创建字符缓冲输入流 BufferedReader br = new BufferedReader(new FileReader("br.txt")); // 创建字符缓冲输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));

15.4.2 特有方法

字符缓冲流的基本方法与普通字符流调用方式一致,不再阐述,我们来看它们具备的特有方法。

  • BufferedReader: public String readLine() : 读一行文字。
  • BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。

15.4.3 newLine()方法写换行符

public static void main(String[] args) throws IOException { // 创建流对象 BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt")); // 写出数据 bw.write("ZY"); // 写出换行 bw.newLine(); bw.write("热巴"); bw.newLine(); bw.write("娜扎"); bw.newLine(); // 释放资源 bw.close(); }

15.4.4 readLine()读取文本行

public static void main(String[] args) throws IOException { // 创建流对象 BufferedReader br = new BufferedReader(new FileReader("in.txt")); // 定义字符串,保存读取的一行文字 String line = null; // 循环读取,读取到最后返回null while ((line = br.readLine())!=null) {System.out.print(line); System.out.println("------"); }//释放资源br.close();}

15.4.5 文本练习

请将文本信息回复顺序

3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小, 悉以咨之,然后施行,必得裨补阙漏,有所广益。
8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰 其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨 之,必能使行阵和睦,优劣得所。
2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理, 不宜偏私,使内外异法也。
1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于 外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失 义,以塞忠谏之路也。
9.今当远离,临表涕零,不知所言。
6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨 臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不 毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝 而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹 息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。

案例分析

  1. 使用流对象逐行读取原文本信息,把读取的信息保存到集合中。
  2. 使用Collections集合工具类中的方法sort,对集合中的元素按照自定义规则排序。
  3. 遍历集合,把集合中排序后的文本在写入到新的记事本中。
public static void main(String[] args) throws IOException { //1.创建ArrayList集合,泛型使用String ArrayList<String> list = new ArrayList<>(); //2.创建BufferedReader对象,构造方法中传递FileReader对象 BufferedReader br = new BufferedReader(new FileReader("IO\\in.txt")); //3.创建BufferedWriter对象,构造方法中传递FileWriter对象 BufferedWriter bw = new BufferedWriter(new FileWriter("IO\\out.txt")); //4.使用BufferedReader对象中的方法readLine,以行的方式读取文本 String line = null; while((line = br.readLine())!=null){ //5.把读取到的文本存储到ArrayList集合中 list.add(line); }//6.使用Collections集合工具类中的方法sort,对集合中的元素按照自定义规则排序 Collections.sort(list, new Comparator<String>() { /*o1-o2:升序 o2-o1:降序 */@Override public int compare(String o1, String o2) { //依次比较集合中两个元素的首字母,升序排序 return o1.charAt(0)-o2.charAt(0); } });//7.遍历ArrayList集合,获取每一个元素 for (String s : list) { //8.使用BufferedWriter对象中的方法wirte,把遍历得到的元素写入到文本中(内存缓冲区中) bw.write(s); //9.写换行 bw.newLine(); bw.flush(); }//10.释放资源 bw.close(); br.close();
}

15.5 打印流

15.5.1 概述

打印流是专门负责数据输出打印的流对象,我们经常使用的控制台输出语句 System.out.println() ,就是打印流实现的输出。 System.out 的运行结果就是PrintStream打印流对象。

  • PrintStream继承OutputStream,本质上是字节输出流。
  • PrintWriter继承Writer,本质上是字符输出流。

打印流的特点:

  • 打印流指负责输出数据,不负责数据来源。
  • 打印流永远不会抛出IOException。
  • 使用PrintWriter打印流,可以开启自动刷新功能。
    • 调用println,printf,format三个方法中的一个才能自动刷新。

15.5.2 PrintWriter类

  • public PrintWriter(String fileName) : 使用指定的文件名创建一个新的打印流。
  • public PrintWriter(OutputStream out) :使用指定的字节输出流构造打印流。
  • public PrintWriter(Writer writer) :使用指定的字符输出流构造打印流。
public static void main(String[] args) throws IOException { // 创建打印流,输出目的是字节输出流 //PrintWriter pw = new PrintWriter(new FileOutputStream("a.txt"),true); //创建打印流,输出目的是字符 PrintWriter pw = new PrintWriter(new FileWriter("a.txt"),true); pw.println(97); pw.println(98); pw.close();
}

注意:打印流输出数据是原样输出,打印97,结果看到就是97,而不是a。

总结

IO流讲完啦,把你的疑惑写在评论区哦

第十五章 IO流(转换流 字符流 字符缓冲流 打印流)相关推荐

  1. 【正点原子STM32连载】第四十五章 SD卡实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  2. 第13天 缓冲、转换、对象(序列化)和打印流

    缓冲.转换.对象(序列化)和打印流 第一章 缓冲流 1.1 概述 1.2 字节缓冲流 1.3 字符缓冲流 1.4 练习:文本排序 第二章 转换流 2.1 字符编码和字符集 字符编码 字符集 2.2 编 ...

  3. 《Erlang程序设计》第十五章 ETS和DETS:大数据的存储机制

    第十五章 ETS和DETS:大数据的存储机制 Table of Contents 第十五章 ETS和DETS:大数据的存储机制 15.1 表的基本操作 创建和打开表 插入表 查找元组 释放表 15.2 ...

  4. 【JAVA SE】第十五章 ArrayList、LinkedList、HashMap和HashSet

    第十五章 ArrayList.LinkedList.HashSet和HashMap 文章目录 第十五章 ArrayList.LinkedList.HashSet和HashMap 一.ArrayList ...

  5. 第十五章 Caché WebSocket

    文章目录 第十五章 Caché WebSocket 使用WebSockets (RFC 6455) Short Polling 短轮询 Long Polling 长轮询 HTTP Streaming ...

  6. 【正点原子Linux连载】第三十五章 Linux内核顶层Makefile详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  7. 【正点原子FPGA连载】第十五章 IP核之FIFO实验 -摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

    1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...

  8. 【正点原子STM32连载】 第二十五章 TFTLCD(MCU屏)实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  9. 【正点原子FPGA连载】第三十五章高速AD/DA实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

最新文章

  1. Linux学习之路-Linux-yum命令【8】---20171217
  2. 一起来用Websocket(一)开篇 Websocket!Socket在HTML5复活
  3. ITK:可视化静态稀疏Whitaker 2D水平设置图层
  4. python接口自动化测试面试题_Python 接口自动化测试实战
  5. 华科考研834计算机网络,2018年华中科技大学834计算机专业基础综合 (模)...
  6. 04 组件与Props
  7. 垃圾回收:引用计数与分代收集机制
  8. WLAN定位技术——(无线信号定位2)
  9. 社交网站 分享 +button
  10. 独家 | 微软披露拓扑量子计算机计划!
  11. 看咒语,知情节?他们用《哈利·波特》让AI学习剧透
  12. 活动选择问题 贪心
  13. 强大的日志分析工具AWStats经典备忘
  14. centos7卸载docker_使用 Docker 部署 Spring Cloud 项目详细步骤
  15. 实验吧 因缺思汀的绕过 By Assassin(with rollup统计)
  16. LeedCode 376. 摆动序列
  17. 分享下自己的经历!2020春招四五月份大厂面经 一:(腾讯、网易、斗鱼、富途、美团、快手)
  18. 怎么运行c语言程序,如何使用C语言进行编程操作,教程在这里,C语言编程快速入门...
  19. B站榜单丨B站UP主行业排行榜周榜
  20. java使用cef,Johness / java-cef / wiki / 使用V49提供的JavaScript Binding进行前后台交互 — Bitbucket...

热门文章

  1. 【并发编程】异步编程CompletableFuture实战
  2. 虚拟机安装mysql步骤
  3. Vue 设置背景图片样式
  4. Microsoft Edge
  5. 二进制、八进制、十进制、十六进制之间的互相转化
  6. 为什么一个数的平方,会变负数?结果令人惊讶(sq代码解析)
  7. Git(用在IDEA中)
  8. 【IntelliJ IDEA】如何汉化成简体中文
  9. Layui_00_03_ Layui图标的使用、新版本和旧版本(layui2.3.0之前)
  10. npm安装electron时报Error: EPERM: operation not permitted, scandir.....