Provides for system input and output through data streams, serialization and the file system.
IO流
缓存、文件、字符串、管道、字节数组、字符数组、过滤、Object对象
bit、字节、字符
字符集、字符编码
字符集(character set)是一个系统支持的所有抽象字符的集合。字符(character)就是各种文字和符号,包括国家文字、标点符号、图形符号、数字等。 常见的编码字符集有: Unicode:也叫统一字符集,它包含了几乎世界上所有的已经发现且需要使用的字符(如中文、英文、德文等)。 ASCII:早期的计算机系统只能处理英文,所以ASCII成为了计算机的缺省字符集,包含了英文所需要的所有字符。 GB2312:中文字符集,包含ASCII字符集。ASCII部分用单字节表示,剩余部分用双字节表示。 GBK:GB2312的扩展,完整包含了GB2312的所有内容。 GB18030:GBK字符集的超集,常叫大汉字字符集,也叫CJK(Chinese,Japanese,Korea)字符集,包含了中、日、韩三国语言中的所有字符。
字符编码(character encoding),是编码字符集的字符和实际的存储值之间的转换关系。 常见的编码方式有: UTF-8(Unicode字符集的编码方式) UTF-16(Unicode字符集的编码方式) UTF-32(Unicode字符集的编码方式) ASCII(ASCII字符集的编码方式)
Java字符串由char序列组成,char数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元,大多数的常用Unicode字符使用一个代码单元就可以表示,而增补字符需要一对代码单元表示。我们所熟知的String类型的length方法,它返回的是UTF-16编码表示的给定字符串的代码单元的数量,如果想要得到代码点的数量,可以调用codePointCount()方法,charAt方法返回位于指定位置的代码单元,codePointAt方法则返回指定位置的代码点。 原文链接: https://blog.csdn.net/nlznlz/article/details/80950596
字节流、字符流
字节流继承inputStream和OutputStream 字符流继承自InputSteamReader和OutputStreamWriter 都实现了Closeable, Flushable, Appendable这些接口 输入输出流是相对于内存而言的
区别
字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据,不能用于处理图像视频等非文本类型的文件。
转换流
NIO
NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。 https://tech.meituan.com/2016/11/04/nio.html 对于NIO,它是非阻塞式,核心类: 1.Buffer为所有的原始类型提供 (Buffer)缓存支持。 2.Charset字符集编码解码解决方案 3.Channel一个新的原始 I/O抽象,用于读写Buffer类型,通道可以认为是一种连接,可以是到特定设备,程序或者是网络的连接
https://ifeve.com/overview/
https://blog.csdn.net/luoshenfu001/article/details/5812041
节点流、处理流
节点流:从或向一个特定的地方(节点)读写数据。如FileInputStream。
处理流(包装流):是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。 一个流对象经过其他流的多次包装,称为流的链接。
装饰者模式
序列化、反序列化
将保存在内存中的对象数据转化为二进制数据流进行传输,任何对象都可以序列化 实现方法:实现java.io.Serializable接口 把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流。ObjectOutputStream(OutputStream oS) 在使用tomcat开发JavaEE相关项目的时候,我们关闭tomcat后,相应的session中的对象就存储在了硬盘上,如果我们想要在tomcat重启的时候能够从tomcat上面读取对应session中的内容,那么保存在session中的内容就必须实现相关的序列化操作,还有jdbc加载驱动用的就是反序列化,将字符串变为对象。ObjectInputStream(inputStream iS) 采用类实现Serializable接口的序列化很简单,Java自动会将非transient修饰属性序列化到指定文件中去。
序列化版本号
反序列化必须拥有 class 文件,但随着项目的升级,class文件也会升级 序列化版本号可自由指定,如果不指定,JVM会根据类信息自己计算一个版本号,这样随着class的升级,就无法正确反序列化;不指定版本号另一个明显隐患是,不利于jvm间的移植,可能class文件没有更改,但不同jvm可能计算的规则不一样,这样也会导致无法反序列化。
transient关键字
一个类某些属性不需要序列化的,可用transient关键字修饰
如果只想将部分属性进行序列化,可以采用如下几种方法:
- 使用transient关键字
- 添加writeObject和readObject方法
- 使用Externalizable实现
Serializable与Externalizable
- Serializable 是标识接口,实现该接口,无需重写任何方法;
Externalizable 接口继承于Serializable,实现该接口,需要重写readExternal和writeExternal方法
- Serializable提供了两种方式进行对象的序列化,
- 采用默认序列化方式,将非transatient和非static的属性进行序列化
- 编写readObject和writeObject完成部分属性的序列化
Externalizable 接口的序列化,需要重写writeExternal和readExternal方法,并且在方法中编写相关的逻辑完成序列化和反序列化
- Externalizable接口的实现方式一定要有默认的无参构造函数
Serializable接口实现,其采用反射机制完成内容恢复,没有一定要有无参构造函数的限制
- 采用Externalizable无需产生序列化ID(serialVersionUID),而Serializable接口则需要
- 相比较Serializable, Externalizable序列化、反序列更加快速,占用相比较小的内存
在项目中,大部分的类还是推荐使用Serializable, 有些类可以使用Externalizable接口,如:
- 完全控制序列的流程和逻辑
- 需要大量的序列化和反序列化操作,而你比较关注资源和性能~ 当然,这种情况下,我们一般还会考虑第三方序列化/反序列化工具,如protobuf等进行序列化和反序列化操作~
File
常用方法
文件分片与文件断点续传
大文件内容查询与排序
FastDFS
FastDFS + nignx 搭建分布式文件服务器
FastDFS + nignx + SpringCloud 实现文件分片与断点续传
参考
https://blog.csdn.net/chengyuqiang/article/details/79183748
https://blog.csdn.net/sinat_37064286/article/details/86537354
https://www.cnblogs.com/whgk/p/5326568.html
https://my.oschina.net/wangmengjun/blog/1588096