文章目录
- 字符流
- 问题导入
- 编码表
- **出现乱码的原因**
- ASCII表
- Unicode表
- 汉字存储和展示过程解析
- 问题导入解答
- 介绍
- 分类
- 字符输出流
- 字符输入流
- 字符缓冲流
- 特殊操作流
- 转化流
- 对象操作流
- 打印流
- 工具包Commons-io
- 介绍
- 分类
- IOUtils类
- FileUtils类
字符流
问题导入
既然字节流能操作所有文件,那为什么还要学习字符流?
使用字节流,将纯文本文件中的数据读取到内存中,可能会出现乱码;同一将中文写入到纯文本文件中,也可能会出现乱码。所以学习字符流,可以针对纯文本文件中的中文数据,进行读写操作
编码表
编码:将看得懂的数据变成看不懂的
解码:将看不懂的数据变成看得懂的
看不懂的数据是指通过编码表后字符存储到计算机的二进制数
出现乱码的原因
编码和解码
ASCII表
- ASCII:包括了数字,英文大小写,还有一些常见的标点符号
- GBK:windows系统默认的码表,兼容ASCII表,包含了汉字等。是中国的码表,一个中文以俩个字节形式存储。
Unicode表
由国际组织ISO制定,是统一的万国码表。最为常见的编码形式:UTF-8
以UTF-8编码后,一个中文以三个字节的形式存储
汉字存储和展示过程解析
问题导入解答
字节流读取文本文件中文会出现乱码:根据上诉编码表的学习,知道了一个中文在GBK是两个字节,在UTF-8中是三个字节,而字节流一次读取一个字节,相当于只读取一个中文的一部分,所有就会出现乱码
字节流拷贝不会出现乱码:这是因为拷贝文件时将源文件中的字节都原封不动的拷贝到目标文件中,在中间没有进行打印
介绍
以字符为单位进行读写操作
可以读取中文的原因:
字符流 = 字节流 + 编码表
底层还是使用字节流读取数据,但是由于指定了编码表,那么第一次就可以读取两个或三个字节数据
注意:不管在哪张码表中,中文的第一个字节一定是负数
分类
字符输出流
- 创建
Writer类:父类,是一个抽象类,不能实例化
FileWriter类:Writer的子类
public FileWriter(File file);
public FileWriter(String fileName);
- 写入
- 释放资源
在字符流中内置了缓冲区(字节数组),刷新了会将缓冲区数据写入到文件中;而关闭流关闭之前会先进行刷新流,确保缓冲区的数据都写入到文件中
字符输入流
- 创建
Reader:父类,是一个抽象类,不能实例化
FileReader:Reader的子类
- 读取
- 释放资源
fe.close();
字符缓冲流
特殊方法
特殊操作流
转化流
作用:读写特定编码表的文件;进行字节流和字符流间的转换
输入流:InputStreamReader
输出流:OutputStreamWriter
注意:自身没有读写数据的能力,需要依靠字节流
//InputStreamReader(InputStream 字节输入流, String 编码表名字)
//创建输入流,并指定关联文件使用的编码表
InputStreamReader isr = new InputStreamReader(new FileInputStream("关联文件"),"GBK");
//OutputStreamWriter(OutputStream 字节输出流, String 编码表名字)
//创建输出流, 并指定关联文件使用的编码表
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("文件"),"GBK");
BufferedWriter bw = new BufferedWriter(osw);
字符流读写数据工作原理
对象操作流
对象操作输入流:从文件中读取存储的对象
对象操作输出流:把内存中创建的对象写入到文件中
IN:ObjectInputStream
方法:Object readObject()
OUT:ObjectOutputStream
方法:void writeObject()
序列化流:把对象序列化后写入到文件或在网络中传输 out
反序列化流:将文件中存储对象(序列化后)读取到内存中或者接收网络中传输的对象 int
注意:一个类要想被序列化,那么此类需要实现Serializable接口
标记接口(空接口)
- 仅有接口的定义,接口内没有任意内容
- 给类的实例添加一个标记(servialVersionUID)
- 只要一个类实现了此接口,表示此类的对象可以被序列化
当想要存储多个对象时,可以将多个对象放到集合中
注意:自身没有读写数据的能力,需要依靠字节流
打印流
作用:
- 在写入数据后可实现自动换行
- 通常用于日志记录
类:PrintStream
public PrintStream(String filePath)
常用方法:
public void print(数据) 打印不换行
public void println(数据) 打印换行
工具包Commons-io
介绍
第三方组织针对IO中大量的API进行简化,只提供一些简单的API方法,就可以实现IO读写操作
分类
IOUtils类
针对IO流进行读写操作(单文件vs单文件)
public static int copy(InputStream in, OutputStream out):
把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
public static long copyLarge(InputStream in, OutputStream out):
把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)
FileUtils类
针对File对象进行读写操作(单文件vs单文件,目录vs目录)
public static void copyFileToDirectory(final File srcFile, final File destFile):
复制文件到另外一个目录下。
public static void copyDirectoryToDirectory(File src , File dest ):
复制src目录到dest位置。
小扩展:
通常Java程序开发完成之后,要进行打包:把程序压缩为一个文件
- jar包:普通的Java程序
- war包:Java Web程序