Skip to content

Java - IO高级流

高级流是对基本流的封装. tip: ctrl + alt +v 自动生成表达式左边,自动生成函数实现


缓冲流

a5c2961b71a9609879d1d0d4e101f903_MD5 当然,字符流本身就有buffer,因此效率不明显,但是有一些常见的好方法.

字节缓冲流

4bae61cd9c313a840790e866731f9516_MD5

构造方法:

513f7de61033071286ec7fa43ef5ac9a_MD5 需要关联某个基本流,实际上是对基本流的包装.

示例

d9a5b2156918f9bc5dc0998874e167b4_MD5 当然实际上是能控制缓冲区的大小的.不多赘述. 关的时候,(我们可以看看源码),只需要关闭缓冲流,就自动帮我们关闭那些基本流. 我们也可以一次读写多个字节: 3e3100d593ce21a78ddeb211b4ce2f4e_MD5 - 有什么区别? 49f0c9ec3f38435f0f61d10e0ed04a94_MD5 e4e517bb1b1dd2e930d229eb72ac765c_MD5 因此,这两者是有区别的.

字符缓冲流

构造方法:

ea88464f594edbfe8097cd68deed2c0f_MD5

特有方法:

f6f444c62bf090957a79d7cef40e0393_MD5

示例

  • readline 969fb0b7b4b25be4225ed5b9754b4079_MD5 循环读取: 1723fb77acafd37353092c4717332b36_MD5
  • newLine 444a4e0ad279cad328ba27656e0d0b3c_MD5 这样,会在bw中追加一个换行.(会根据平台的不同追加不同的换行)

续写

注意,如果想开启续写要在基本流中加: e78930a0228262e660c42ddf2f7e56c0_MD5

误区

  • 能不能说字符缓冲流的缓冲区是8192字节? 答不是.是8192个字符的缓冲区.Java当中一个字符是两个字节,那么实际上是要乘2,一共16字节的buffer
  • FileReader有自己的缓冲区,而关联在某个FileReader上的BufferedReader也有自己的缓冲区,两者的缓冲区之间的拷贝是否会影响效率? 答:不会.bufferReader会直接从FileReader的底层去读取数据到自己的缓冲区.
  • java当中的char是2字节,但是我们知道utf8当中的汉字是3字节,那么一个char如何能存储一个汉字的? 答:实际上,Java的char/String用的是UTF16.UTF16当中,一个汉字只有两字节,是可以存储在一个char当中的,当我们在与外部交互的时候需要utf8,那么会进行转化:
    String str = "中文";
    byte[] utf8Bytes = str.getBytes("UTF-8"); // "中"转为3字节,"文"转为3字节
    String str = new String(utf8Bytes, "UTF-8"); // 自动将UTF-8解码为UTF-16
    
    拓展:utf16中的字符,有可能是2个字节,但也有可能是4个字节.在存储4个字节的情况下,一个字符会被用两个char进行表示.
  • 如果没有close,也没有flush,那么,缓冲区的数据会丢失.因此,数据丢失时应该排查是否close了.

转换流

7be6f89819e6029021ef2ce38a94455d_MD5 e0462e00c9ba7651099bb7851fb99594_MD5 9304a7621532d869364929713fd1caf6_MD5

作用:

d8c75325fc710f9d25f1d3fa18b13a8e_MD5 第一种方式在JDK11后被淘汰了

样例:

50aa10a8a65b762344bb86c2e65f7a0b_MD5

写入

4fbcd4c62e14a24cb0cff4c835ce5ed1_MD5 替代方案: JDK11之后,FileReader出现了新的构造函数. 6c134c949bbeb9e4c671d855f012be11_MD5

写出

a4c1464d00da871e66012d00a7ef5859_MD5 替代方案: 9477853b9f9d471d99fb96db468f0ef0_MD5

综合应用

cc6411827faa1626a6d25b5d675e63bb_MD5

使用字符流方法

397b0662f8adf928bbb3f76f4e7a4cfe_MD5 也就是说,BufferedReader是可以关联InputStreamReader的.


序列化流/对象操作输出输出流

33aaa833fe456b737bd46c37009fb533_MD5 可以把数据写入到文件当中,写入的内容是肉眼不可读的.因此避免了被别人修改.

成员方法

1985f675bfb3045a6c0b80b231f74350_MD5

示例

被写的对象的类需要实现Serializable接口. 但是这是一个标记型接口: 742cc2922054d9b1dc1b9fed0db369fe_MD5 9d715d726a8a05152c1b5e56c48ec936_MD5 143c5964ffc54c4dbcb64c74aac9765e_MD5

细节

序列号serialVersionUID

如果一个类可序列化,那么java会把根据它的成员等计算出一个序列号,类似于版本号.在写入文件的时候,会顺带把这个类的序列号写入.但是如果这时候修改了这个类的java代码,那么可能会导致版本号发生改变,从而导致反序列化的时候两个序列号不一样. 怎么办?我们手动规定版本号: 50d4c7f762c8009dac70020cb2e7830b_MD5 要求serialVersionUID这个变量名不能修改. 推荐的写法: IDEA设置一下: 6ccbe6e5c6649a7edd14c3e3c7a8924e_MD5

这时候就会提示: b65cac811a62f63ae41492ddc2ca3088_MD5 点击add,就会手动生成一个.这个值是会根据成员等信息计算出来的,因此建议在javabean写完之后再生成. 703622fef5af197730b2759081b7025f_MD5

这样,如果类修改了,那么反序列化后的对象与原来的对象相比,如果新增了字段,那么就会变成初始化值.

transient瞬态关键字

3cc9a67023fc133267cdce191c2ede7c_MD5 这样就可以保证某个字段不会被序列化.在读取时,这个字段会被初始化为默认值.

多次读取

如果不知道文件里存了几个对象,怎么办? 如果一直读,那么读到文件结尾时,会抛出异常.但我们写代码一般不会主动制造异常,怎么办?

我们一般会把要序列化的对象存在ArrayList里,从而方便读取: f122ca3b6c3a1786f3a16a0a9b587e96_MD5 282a3a349ab54d4802f8b16442c1cff9_MD5


打印流

020a34d456fc633d86cb1acb7046d7f5_MD5 只有输出流,没有输入流. 29002da6bc1131c84b26685688db1d39_MD5 注意,只有特有方法才有.

字节打印流

构造函数

300daf8ab064c56b4f194c96bbfe252b_MD5 由于字节流底层没有缓冲区,因此后两个方法开不开自动刷新都一样.

成员方法

c2f8b951bda1e7e79095944dda999f64_MD5

示例

db21154d258ba6c5bf200f2bcb67115c_MD5

字符打印流

191dd824ee7381deff9aa102f8f7283e_MD5

构造方法

6a5eaacfd32e45902d4048519457b19c_MD5

成员方法

01f3a16ccdf57adc3d5e16f6efd776d5_MD5

示例

161a2cf7f5177721fcdd73e03ec1ab87_MD5

打印流和System.out的关系

496955036130307d12a9dc7e053eaf9d_MD5 System.out实际上是System类的一个静态成员变量 这是JVM在启动的时候默认创建的.默认指向控制台.


解压缩流/压缩流

f63f7617c277b04bbc167f26a8938bf7_MD5

解压缩流

只能为.zip后缀的. 压缩包中的每个文件都对应java中的一个zipENtry对象,解压的本质就是把每一个ZipEntry按照层级拷贝到本地的另一个文件夹当中. 1.如果获取完了,那么就会返回null. 2.子文件夹中的东西也能获取. fa09eb7fa7299087313f83dbcaf0d619_MD5 621dd466baf30526b607d2112a976fe6_MD5

压缩流

压缩的本质:把每一个文件/文件夹看成zipEntry对象放到压缩包中.

压缩文件:

1e88e1cacd9642b6950237d985d59fe9_MD5 05dce04005865711a108b96df06ad7bf_MD5

压缩文件夹

先说一个细节:如果我们这样写:05ba47bc8db9dbd8c906a8062444ee4c_MD5 那么,压缩包里会创建一个目录aaa,然后里面有一个a.txt. 0a61c66b6df89c305c5ba84ee4cd58ac_MD5 ddfbd8f13251cc76616c60430e7fadaa_MD5 1d128d800c60dd12eda174417d512096_MD5


commons-io

java的压缩包就是jar.因此我们使用的时候需要把jar导入. 使用第三方: 8b0736229ab12aa8b8e747c683949289_MD5 导入的时候导入.jar后缀的,不要导入sources. 2f90756d96db69331f6a742089db8c40_MD5 965c81b97db05ff53f151cf019824859_MD5

hutool工具包(常用)(也叫糊涂包)

3e415fb7f4ae49b6b0e9c1506321ba0b_MD5


制作假数据 - 爬取数据

28ed60d2db55772410d01080a023f7a2_MD5 b99b4771a1003f9e2ec714c0a59da695_MD5 6098ec8fd363b4f0dd66b3f099ba00b4_MD5 tip:中文正则生成:feae3d21e656793af630b0f18a15138c_MD5 76b7c8d30385614afc3b50ccbbf8b5be_MD5 1c2d9372c0553dd8ee36abea64b883fa_MD5 拼接函数就不写了. 5c214b51ee510832344a8aaada140d90_MD5

制作假数据 - 糊涂包

把上面的改成用第三方库: 772efa18e07233ceed465fae6fa39082_MD5 0df132e2b06666289c95575dcc0ee07e_MD5


带权重的随机挑选

在负载均衡网关中,经常使用这个方法. 6a2e6c80f186cc3659530d29bd5de403_MD5 ef0904b770536017e0eee2e7afc9fd78_MD5