Java中IO流详解

本文介绍了字符流在处理文本文件尤其是中文数据时的重要性,详细解释了乱码产生的原因,涉及ASCII和Unicode编码表,以及如何通过字符流、编码转化流和工具包如Commons-io的IOUtils类进行有效的中文读写和文件操作。
摘要由CSDN通过智能技术生成


字符流

问题导入

既然字节流能操作所有文件,那为什么还要学习字符流?
使用字节流,将纯文本文件中的数据读取到内存中,可能会出现乱码;同一将中文写入到纯文本文件中,也可能会出现乱码。所以学习字符流,可以针对纯文本文件中的中文数据,进行读写操作

编码表

编码:将看得懂的数据变成看不懂的
解码:将看不懂的数据变成看得懂的
看不懂的数据是指通过编码表后字符存储到计算机的二进制数

出现乱码的原因

编码和解码

ASCII表

  • ASCII:包括了数字,英文大小写,还有一些常见的标点符号
  • GBK:windows系统默认的码表,兼容ASCII表,包含了汉字等。是中国的码表,一个中文以俩个字节形式存储。

Unicode表

由国际组织ISO制定,是统一的万国码表。最为常见的编码形式:UTF-8
以UTF-8编码后,一个中文以三个字节的形式存储
image-20210415215927246.png

汉字存储和展示过程解析

image-20210415215943288.png

问题导入解答

字节流读取文本文件中文会出现乱码:根据上诉编码表的学习,知道了一个中文在GBK是两个字节,在UTF-8中是三个字节,而字节流一次读取一个字节,相当于只读取一个中文的一部分,所有就会出现乱码
字节流拷贝不会出现乱码:这是因为拷贝文件时将源文件中的字节都原封不动的拷贝到目标文件中,在中间没有进行打印

介绍

以字符为单位进行读写操作
可以读取中文的原因
字符流 = 字节流 + 编码表
底层还是使用字节流读取数据,但是由于指定了编码表,那么第一次就可以读取两个或三个字节数据
注意:不管在哪张码表中,中文的第一个字节一定是负数

分类

字符输出流

  1. 创建

Writer类:父类,是一个抽象类,不能实例化
FileWriter类:Writer的子类

public FileWriter(File file);
public FileWriter(String fileName);
  1. 写入

Snipaste_2024-04-06_10-55-06.png

  1. 释放资源

Snipaste_2024-04-06_10-56-31.png
在字符流中内置了缓冲区(字节数组),刷新了会将缓冲区数据写入到文件中;而关闭流关闭之前会先进行刷新流,确保缓冲区的数据都写入到文件中

字符输入流

  1. 创建

Reader:父类,是一个抽象类,不能实例化
FileReader:Reader的子类

  1. 读取

Snipaste_2024-04-06_11-26-16.png

  1. 释放资源

fe.close();

字符缓冲流

Snipaste_2024-04-06_15-11-37.png
特殊方法
Snipaste_2024-04-06_15-21-42.png

特殊操作流

转化流

作用:读写特定编码表的文件;进行字节流和字符流间的转换
输入流: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);

字符流读写数据工作原理
Snipaste_2024-04-06_16-27-14.png

对象操作流

对象操作输入流:从文件中读取存储的对象
对象操作输出流:把内存中创建的对象写入到文件中

IN:ObjectInputStream
方法:Object  readObject()
OUT:ObjectOutputStream
方法:void  writeObject()

序列化流:把对象序列化后写入到文件或在网络中传输 out
反序列化流:将文件中存储对象(序列化后)读取到内存中或者接收网络中传输的对象 int
注意:一个类要想被序列化,那么此类需要实现Serializable接口
标记接口(空接口)

  • 仅有接口的定义,接口内没有任意内容
  • 给类的实例添加一个标记(servialVersionUID)
  • 只要一个类实现了此接口,表示此类的对象可以被序列化

当想要存储多个对象时,可以将多个对象放到集合中
Snipaste_2024-04-06_19-04-10.png
注意:自身没有读写数据的能力,需要依靠字节流

打印流

作用

  1. 在写入数据后可实现自动换行
  2. 通常用于日志记录

: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程序
  • 10
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@Zeal

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值