Java 的IO
任何编程语言都要和文件打交道,都要有输入输出的操作。
基于此,我们有字节、字符的输入、输出流的概念。
输入输出的概念是相对的,一般我们都是站在编写的程序下的角度看的。
我们还有 字节、字符的概念。
-
字节:
计算机存储东西,一般都是基于字节来存储的,也就是我们看到的五彩斑斓的电脑世界(比如说视频、图像、音频啊等等的),他们在内存中,在磁盘中,都是以 字节 的形式来存储的。(或者说是那些二进制数字)
1字节 = 8位 (1 Byte = 8 bit)
-
字符:
就很简单,一个字符就代表一个我们所认知的符号。
这么说吧,字符串我们还算是比较熟悉的了,字符串就是 很多个字符串在一起,可以看成是很多个字符的序列。
在 Java 里, 字符用 char 或者 Character 来表示 ,在内存大小里占 2个字节(和他的编码方式有关)。
先了解下编码和解码的概念
编码: 把 字符 转换成 字节的过程。(编成计算机所理解的东西)
解码: 把 字节 转换成 字符的过程。(解成人类所理解的东西)
如果编码和解码的过程,使用的不是一套编码方式,就会出现乱码的现象。
有一些简单的、常见的编码方式:
- GBK编码: 一个中文占2个字节,一个英文占1个字节。
- UTF-8编码: 一个中文占3个字节,一个英文占1字节。
- UTF-16be编码:不管一个中文,还是一个英文,都是占2个字节。
(be指的是大端方式: big endian。 相应的有小端方式,le: little endian)
Java 内存的编码方式,使用的就是双字节编码——UTF-16be编码,这样就能让一个中文或英文使用一个 char 来存储了。
Java 中 String 的编码方式: String 的默认编码方式跟平台有关,一般都是 UTF-8编码。
// 将 “中文” 这个字符串, 用 UTF-8 的编码方式,编码成 字节数组。
byte[] bytes = "中文".getBytes("UTF-8"); // 无参的话,默认就是 UTF-8
// 将 字节数组bytes 里的内容,用UTF-8的编码方式,解码成 字符串。
String str = new String(bytes, "UTF-8")
序列化 和 反序列化
趁热打铁,其实序列化和反序列化 与 编码和解码 的概念还是挺像的,但也只是像,他们还是有区别的!
先了解概念:
序列化: 将 对象 转换成字节,方便存储和传输。 (注意是 对象,区别就在这里,序列化只是保存对象的状态)
我们不能对 静态变量 进行序列化,因为序列化保存的 对象的状态,而静态变量是,属于类的状态。
反序列化: 顾名思义,就是序列化的反操作。
Java 中的序列化和反序列化:
必须实现 Serializable 接口(虽然这个接口没有任何方法需要实现),否则就会抛 不支持序列化的异常。
ObjectOutputStream.writeObject(Object obj ) ,进行序列化,将对象写入到文件。
Object obj = ObjectInputStream.readObject( ),进行反序列化,将文件读取到对象中。
transient 关键字:
被 transient 关键字修饰的属性不会被 序列化。
比如 ArrayList 中 存储数据的数组 elementData 就被 transient 修饰,他不能被序列化。
因为他是动态扩容的,并不是所有空间都需要序列化。
可以重写他的序列化 和 反序列化的 方法。
关于字符的 IO
字符流是用到了缓冲区的概念的,而字节流是没有缓冲区的。
我们需要把缓冲区的内容搞出来。(.close( ) 方法前会清空缓冲区, 或者手动调用 .flush( ) 方法来刷新缓冲区)
-
字符输入流: 抽象类: Reader; 可以用 FileReader 来实现。
-
字符输出流: 抽象类: Writer; 可以用 FileWriter 来实现。
但是不管是 内存、磁盘、还是网络传输,存储的最小单位都是字节。
我们在程序中打交道的往往是 字符形式的数据。
所以就有 字符 和 字节 转换的需求:
字节流 解码成 字符流:InputStreamReader (读进来的,我们需要用)
字符流 编码成 字节流:OutputStreamWriter (写出去的,计算机需要用)
关于字节的 IO
-
字节输入流:抽象类:InputStream; 可以用 FileInputStream 来实现。
-
字节输出流:抽象类:OutputStream; 可以用 FileOutputStream 来实现。
这些类设计,用到了 装饰者模式 这个设计模式。
关于文件
Java 中用 File 类 来表示文件或者目录,但他不表示文件里的内容。
从 Java7 开始, 可以用 Files 和 Paths 类来代替了。