java IO读写

IO简介

数据流是一组有序,有起点和终点的字节的数据序列。包括输入流和输出流。
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因
此Java中的流分为两种: 1) 字节流:数据流中最小的数据单元是字节 2) 字符流:数据流中最小的数据单元是字符,
Java中的字符是Unicode编码,一个字符占用两个字节。
Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;
一个接口指的是Serializable。掌握了这些就掌握了Java I/O的精髓了。
Java I/O主要包括如下3层次:

  1. 流式部分——最主要的部分。如:OutputStream、InputStream、Writer、Reader等 2. 非流式部分——如:File类、RandomAccessFile类和FileDescriptor等类
  2. 其他——文件读取部分的与安全相关的类,如:SerializablePermission类,以及与本地操作系统相关的文件系
    统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。

在这里插入图片描述
IO详细介绍

在Android 平台,从应用的角度出发,我们最需要关注和研究的就是 字节流(Stream)字符流(Reader/Writer) 和 File/ RandomAccessFile。当我们需要的时候再深入研究也未尝不是一件好事。

关于字符和字节,例如文本文件,XML这些都是用字符流来读取和写入。
而如RAR,EXE文件,图片等非文本,则用字节流来读取和写入。面对如此复杂的类关系,有一个点是我们必须要首先掌握的,那就是设计模式中的装饰模式,学会并理解装饰模式是搞懂流必备的前提条件。

以上都是废话,暂时没有那么大的精力从最基础开始讲起,本文主要是记录一下要点,方便回忆。


这是一张字节流的总结图,可以看出有out就有int。
write和read是从内存的角度来讲,out:从内存里写到文件,read:从文件里写入内存。

将一个文件读取到内存我们一般都是:

使用FilterInputString,然后再用BufferedInPutString。
FilterInputString是对InputString+传入一个文件的包装,FileInputString实现了IntputString。

内部都是装饰模式,其实说到底还是使用IntputString去工作。
BufferedInputString是为了提升速度,一次读取一个字节和一次读取100个字节,当然后者更快,至于它一次读取多少字节其实没有必要深究,除非特殊需求,你设置太大你的CPU寄存器也受不了。
当初开始学IO流的时候记得老师从最基础的自己实现一个类似Buffered缓存,然后具体演示比较了跟JDK提供的buffered的区别,当初好像是一次1m,差不多是这个缓存,总之一句话,没特殊需求直接用JDK的就行。

反之,有int肯定有out,看看上面那张图都是流的读取输出都是成对出现的,这是最常用的,其他几个有一定了解就行,反之用法也是一样。

DataOutputStream这个也是一样,可以根据数据的类型输出读取,这个类型指的是java的基本类型。

字符流

首先从上图我们也可以看到字符流的读写也是成对地出现,字符流我们用得比较少,一般都是使用字节流,因为我们一般读取png exe json jar xml等等都只需要用到字节流,那么为什么还要有字符流呢?

我们知道英文是一个byte8位就可以完全表达了,但是中文不行,它需要用到一个字符来表达,同时使用字符还会涉及到编码问题,字符流的读取往往还需要传入编码格式。

字符它也是使用装饰模式,例如read,底层一个read,FilterRead实现了,同时自身声明为抽象流,作为基础组件被使用。

整个一个装饰模式的使用过程大概是这样的:
Writer- >FilterWriter->BufferedWriter->OutputStreamWriter->FileWriter->其他

完整的创建过程:
BufferedWriter bufferedWriter = BufferedWriter(new OutputStringWrier(new FileOutputString(new File(“xxxx.txt”),“GBK”))

实际上new OutputStringWrier(new FileOutputString(new File(“xxxx.txt”) = FileWriter(“xxxx.txt”);

因为FileWriter继承使用的是FileOutputString,直接代替这个OutputStringWrier给Buffered
还是装饰模式的运用。

flush方法:强制IO,当我们用buffered缓存区写入的时候,如果装满缓冲去会自动写入到目的文件当中,当最后一次不满缓存区的时候,调用flush会进行强制不用等直接写入。

当然这是字节流需要,字符流的bufferedWrite是不用的,因为close方法会自动帮你调用flush

buffered加快速速度的原理:读的时候一次读1000字节,然后回来写入内存,和一次读一次回来写一次的区别:IO操作都是堵塞操作,当你进行读写的时候其实让出了CPU的执行权,等待读写完毕重新进入就绪状态。
让出CPU执行权涉及CPU轮转概念,如果有对并发不了解的朋友可以看:

读写一次1kb和1000kb,减少磁盘缓冲头的调用,这也是优化。

RandomAccessFile的使用

//rw表示我可以写也可以读
RandomAccessFile rsfWriter = new RandomAccessFile(“xxx.txt”,“rw”);
//不改变文件大小,意思是前面是空的,跟空格不一样,空格可是有实际意义存在。
//可以理解将光标移动1000,下一个将从1001开始读写。文件的长度依然是0
rsfWriter.seek(1000); //真正意义是从某个位置开始读写

//设置了文件的长度,文件的长度就变成1000了
rsfWriter.setLength(1000); //给前面的位置预留控件

rsfWriter.wroterXXX();//使用对应的数据类型方法写数据进去

应用场景:网络数据断点续传

NIO:FileChannel
使用了ByteBuffered去工作,更底层的源码看不到了,android里面使用的非常少,有兴趣的朋友可以自行去了解,作用:速度更快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值