java读取流_java io流(核心:读进来,写出去)

一、流概念和作用

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流。流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

二、流存在的意义

我们在进行数据传输时有这三个特点:1.数据的传输量很大;2.内存有限;3.带宽有限。所以需要使用流来解决这些问题。而流可以逐步的传输所有数据,不会占用太多的内存。例如下载文件时,并不会占用太多的内存,而是在内存中开辟一个缓冲区,一点一点的传输数据,当这个缓冲区满了后就直接写到磁盘。

三、流的原理浅析

java IO流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系,Java IO流的40多个类都是从如下4个抽象类基类中派生出来的。

InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。

OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

注:它们都是一些抽象基类,无法直接创建实例。

四、IO流的分类

java输入/输出流体系中常用的流的分类如下

c47433e2904879beb4cb58f9a7c0ce6f.png

InputStreamReader和OutputStreamWriter是字符和字节的桥梁,也可称之为字符转换流。原理:字节流+编码。

FileReader和FileWriter作为子类,仅作为操作字符文件的便捷类存在。当操作的字符文件,使用的是默认编码表时可以不用父类,而直接使用子类完成操作,简化代码。

一旦要指定其他编码时,不能使用子类,必须使用字符转换流。

public class InputStreamReader extends Reader

InputStreamReader 是字节流通向字符流的桥梁

public class OutputStreamWriter extends Writer

OutputStreamWriter 是字符流通向字节流的桥梁

五、按照流操作对象分类

2b82b59cc7c3000e3719bacaff3a82c7.png

1.按照流的流向分,可以分为输入流和输出流;

输入流: 只能从中读取数据,而不能向其写入数据。

输出流:只能向其写入数据,而不能向其读取数据。

2.按照操作单元划分,可以划分为字节流和字符流;

字节流和字符流的用法几乎完全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元为8位的字节,字符流操作的是数据单元为16位的字符。

设备上的数据无论是图片或者视频,文字,它们都以二进制存储的。二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节。意味着,字节流可以处理设备上的所有数据,而字符流只能处理字符数据。 字符流能实现的功能字节流都能实现,反之不一定。

结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

3.按照流的角色划分为节点流和处理流。

可以向一个特定的IO设备(如磁盘,网络)读/写数据的流,称为节点流。节点流也被称为低级流。当使用节点流进行输入/输出时程序直接连接到实际的数据源,和实际的输出/输入节点连接。

处理流则用于对一个已存在的流进行连接和封装,通过封装后的流来实现数据的读/写功能。处理流也被称为高级流。处理流也就是对流进行了再包装,从而达到优化系统性能的目的。

2cb7cc652d7c934c0f05d7285feb4261.png

5e4ac69120a4264e00a93a8bac5d4e9d.png

缓冲流:

缓冲流(buffering)是处理流的一种,它是要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能, 提高了读写的效率,同时增加了一些新的方法。例如:BufferedReader中的readLine方法, BufferedWriter中的newLine方法,对I/O进行缓冲是一种常见的性能优化,缓冲流为I/O流增加了内存缓冲区,增加缓冲区的两个目的:

(1)允许Java的I/O一次不只操作一个字符,这样可提高整个系统的性能;

(2)由于有缓冲区,使得在流上执行skip、mark和reset方法都成为可能。

缓冲区的工作原理:1、使用底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。2、通过缓冲区的read()方法从缓冲区获取具体的数据,这样就提高了效率。

//字符输入缓冲流

BufferedReader(Reader in)//创建一个32字节的缓冲区

BufferedReader(Reader in, int size)//size为自定义缓存区的大小

//字符输出缓冲流

BufferedWriter(Writer out)

BufferedWriter(Writer out, int size)

//字节输入缓冲流

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in, int size)

//字节输出缓冲流

BufferedOutputStream(OutputStream in)

BufferedOutputStream(OutputStream in, int size)

备注:

(1)字节缓冲输入流BufferedInputStream除了支持read和skip方法以外,还支持其父类的mark和reset方法;

(2)BufferedReader提供了一种新的ReadLine方法用于读取一行字符串(以\r或\n分隔);

(3)BufferedWriter提供了一种新的newLine方法用于写入一个行分隔符;

(4)对于输出的缓冲流,BufferedWriter和BufferedOutputStream,写出的数据会先在内存中缓存,使用flush()方法将会使内存的数据立刻全部写出。

六、流的重要特性

1、流是Java 的1个类,但类不是流。

2、数据并不会在流里自动流动,因此需要我们调用流的方法,一次传输一定量的数据。

3、一个流对象只有一个传输方向,也就是说流是单向的, 数据要么从程序到设备(OutputStream), 要么从设备到程序(InputStream)。

七、何为NIO,和传统Io有何区别

我们使用InputStream从输入流中读取数据时,如果没有读取到有效的数据,程序将在此处阻塞该线程的执行。传统的输入流和输出流都是阻塞式的进行输入和输出。 传统的输入流、输出流都是通过字节的移动来处理的(即使我们不直接处理字节流,但底层实现还是依赖于字节处理)。也就是说,面向流的输入和输出一次只能处理一个字节,因此面向流的输入和输出效率通常不高。

从JDk1.4开始,java提供了一系列改进的输入和输出处理的新功能,这些功能被统称为新IO(NIO)。新增了许多用于处理输入和输出的类,这些类都被放在java.nio包及其子包下,并且对原io的很多类都以NIO为基础进行了改写,新增了满足NIO的功能,所以从效率上来说IO和NIO差不了太多。

NIO采用了内存映射对象的方式来处理输入和输出,NIO将文件或者文件的一块区域映射到内存中,这样就可以像访问内存一样来访问文件。通过这种方式来进行输入/输出比传统的输入和输出要快的多。

八、在开发中正确使用IO进行开发

如果是操作二进制文件那我们就使用字节流,如果操作的是文本文件那我们就使用字符流。尽可能多的使用处理流,这会使我们的代码更加灵活,复用性更好。

九、参考博文

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值