标签:操作 没有 字符数组 通过 英语 writer 二进制 基础 标准
既然字节流可以操作所有文件,那么为什么还要学习字符流?
如果利用字节流,把文本文件中的中文,读取到内存中,有可能出现乱码
如果利用字节流,把中文写到文本文件中,也有可能出现乱码
字符流的介绍
字符流 = 字节流 + 编码表
中文的字节存储方式
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
基础知识:
计算机中存储的信息都是用二进制数表示的
按照某种规则,将字符变成二进制,在存储到计算机中,称为编码。
按照同样的规则,将存储在计算机中的二进制数解析显示出来,称为解码。
编码和解码的方式必须一致,否则会导致乱码。
简单理解:
存储一个字符a,首先需在码表中查到对应的数字时97,然后转换成二进制进行存储。
读取的时候,先把二进制解析出来,再转成97,通过97查找对应的字符时a。
什么是字符集
是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
l计算机要准确的存储和识别各种字符集符号,就需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBXXX字符集、Unicode字符集等
常见的字符集
ASCII字符集:
lASCII:是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)
基本的ASCII字符集,使用7位表示一个字符,共128字符。ASCII的扩展字符集使用8位表示一个字符,共256字符,方便支持欧洲常用字符。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
GBXXX字符集:
GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等,一个中文以两个字节的形式存储,但不包含世界上各国的文字。
Unicode字符集:
UTF-8编码:可以用来表示Unicode标准中任意字符,它是电子邮件、网页及其他存储或传送文字的应用 中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。它使用一至四个字节为每个字符编码
编码规则:
128个US-ASCII字符,只需一个字节编码
拉丁文等字符,需要二个字节编码
大部分常用字(含中文),使用三个字节编码
其他极少使用的Unicode辅助字符,使用四字节编码
相关方法
方法名 | 说明 |
---|---|
byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节 |
byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节 |
String(byte[] bytes) | 使用平台的默认字符集解码指定的字节数组来创建字符串 |
String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来创建字符串 |
代码演示
package com.itheima.charstream1; import java.io.UnsupportedEncodingException; import java.util.Arrays; public class CharStreamDemo2 { public static void main(String[] args) throws UnsupportedEncodingException { //method1(); // String(byte[] bytes): //通过使用平台的默认字符集解码指定的字节数组来构造新的 String // String(byte[] bytes, String charsetName): //通过指定的字符集解码指定的字节数组来构造新的 String //UTF-8 byte [] bytes1 = {-23, -69, -111, -23, -87, -84, -25, -88, -117, -27, -70, -113, -27, -111, -104}; //gbk byte [] bytes2 = {-70, -38, -62, -19, -77, -52, -48, -14, -44, -79}; //利用默认的UTF-8进行解码 String s1 = new String(bytes1); System.out.println(s1);//黑马程序员 //利用指定的GBK进行解码 String s2 = new String(bytes2,"gbk"); System.out.println(s2);//黑马程序员 } private static void method1() throws UnsupportedEncodingException { // byte[] getBytes(): //使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 // byte[] getBytes(String charsetName): //使用指定的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 String s = "黑马程序员"; //利用idea默认的UTF-8将中文编码为一系列的字节 byte[] bytes1 = s.getBytes(); System.out.println(Arrays.toString(bytes1)); //byte[] bytes2 = s.getBytes("UTF-8"); byte[] bytes2 = s.getBytes("GBK"); System.out.println(Arrays.toString(bytes2)); } }
为什么字节流读取文本文件,可能会出现乱码?
因为字节流一次读一个字节,而不管GBK还是UTF-8一个中文都是多个字节,用字节流每次只能读其中的一部分,所以就会出现乱码问题。
字符流读取中文的过程
字符流=字节流+编码表
基础知识:
不管是在哪张码表当中,中文的第一个字节一定是负数。
小结:
1.想要进行拷贝,一律使用字节流或者字节缓冲流
2.想要把文本文件中的数据读到内存中,请使用字符输入流。
想要把内存中的数据写到文本文件中,请使用字符输出流。
3.GBK码表中一个中文两个字节,UTF-8编码格式一个中文3个字节
介绍
Writer: 用于写入字符流的抽象父类
FileWriter: 用于写入字符流的常用子类
构造方法
方法名 | 说明 |
---|---|
FileWriter(File file) |
根据给定的 File 对象构造一个 FileWriter 对象、 |
FileWriter(File file, boolean append) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象 |
FileWriter(String fileName, boolean append) | 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象 |
方法名 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(char[] cbuf) | 写出一个字符数组 |
void write(char[] cbuf, int off, int len) | 写出字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str, int off, int len) |
方法名 | 说明 |
---|---|
flush() | 刷新流,之后还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
package com.itheima.charstream1; import java.io.File; import java.io.FileWriter; import java.io.IOException; public class CharStreamDemo3 { //创建字符输出流的对象 public static void main(String[] args) throws IOException { //FileWriter fw=new FileWriter(new File("charstream\\a.txt")); FileWriter fw=new FileWriter("charstream\\a.txt"); /*//写出数据 //void write(int c) 写一个字符 fw.write(97); fw.write(98); fw.write(99);*/ /* //void write(char[] cbuf) 写出一个字符数组 char[] chars={97,98,99,100,101}; fw.write(chars);*/ /*//void write(char[] cbuf, int off, int len) 写出字符数组的一部分 char[] chars={97,98,99,100,101}; fw.write(chars,0,3);*/ /* //void write(String str) 写一个字符串 String line="黑马程序员abc"; fw.write(line);*/ //void write(String str, int off, int len) 写一个字符串的一部分 String line="黑马程序员abc"; fw.write(line,0,2); fw.close(); } }
步骤:
1.创建字符输出流对象
注意事项:
如果文件不存在,就创建,但是要保证父级路径存在。
如果文件存在就清空
2.写数据
注意事项:
写出int类型的整数,实际写出的是整数在码表上对应的字母。
写出字符串数据,是把字符串本身原样写出。
3.释放资源
注意事项:
每次使用完流必须要释放资源
标签:操作 没有 字符数组 通过 英语 writer 二进制 基础 标准
原文地址:https://www.cnblogs.com/faded8679/p/13944446.html