《On Java进阶卷》阅读笔记(五)

第7章 IO系统

I/O流:

IO有很多不同的来源和去处,如文件、控制台网络连接等,而且还涉及需求以很多种方式,如顺序读取、随机访问、缓冲、字符、按行读取、按字读取等。

Java8的函数式流相关的类和IO流之间并无关联。

IO流隐藏了实际的IO设备中数据情况的下列细节:

  1. 字节流用于处理原始的二进制数据。
  2. 字符流用于处理字符数据。它会自动处理和本地字符集间的相互转换。
  3. 缓冲区流提升了性能。它通过减少调用本地API的次数,优化了输入和输出。

输入里read()方法,用于从字节数组中读取单个字节或字节数组。

输出里write()方法,用于写入单个字节或字节数组。

各种InputStream类型:

  1. 字节数组
  2. 字符串对象
  3. 文件
  4. 管道
  5. 其他流组成的序列,这样可以将这些流合并成单个流。
  6. 其他源,例如外部网络连接。

功能

使用方法

ByteArrayInputStream

使内存中的缓冲区可以充当InputStream

作为一种数据源:通过将其连接到FilterInputStream对象来提供有用的接口

StringBufferInputStream

将字符串转换为InputStream

作为一种数据源:通过将其连接到FilterInputStream对象来提供有用的接口

FileInputStream

用于从一个文件中读取信息

作为一种数据源:通过将其连接到FilterInputStream对象来提供有用的接口

PipedInputStream

用于生成写入到对应的PipedOutputStream中的数据。它实现了管道传输的概念

作为一种多线程形式数据源:通过将其连接到FilterInputStream对象来提供有用的接口

SequenceInputStream

将两个以上的InputStream转换为单个InputStream

作为一种数据源:通过将其连接到FilterInputStream对象来提供有用的接口

FilterInputStream

作为装饰器接口的抽象类,装饰器用来为其他InputStream类提供有用的功能。

各种OutputStream类型:

功能

使用方法

ByteArrayOutputStream

在内存创建一块缓冲区,所有发送到流中的数据都被放在该缓冲区

用于指定数据的目的地:通过将其连接到FilterOutputStream对象来提供有用的接口

FileOutputStream

用于向文件发送信息

用于指定数据的目的地:通过将其连接到FilterOutputStram对象来提供有用的接口

PipedOutputStream

向其中写入的任何信息都将自动作为对应的PipedInputStream的输入。实现了管道传输的概念。

用于为多线程制定数据的目的地:通过将其连接到FilterOutputStream对象来提供有用的接口

FilterOutputStream

作为装饰器接口的抽象类,装饰器用来为其他OutputStream类提供有用的功能

各种FilterInputStream类型:

功能

使用方法

DataInputStream

与DataOutputStream配合使用,以可移植的方式从流中读取基本类型,int、char、long等

包含用于读取基本类型的全部接口

BufferedInputStream

用于防止在每次需要更多数据时都进行物理上的读取。相等于声明使用缓冲区

这本质上并为提供接口,只是为进程增加缓冲操作而已,需要与接口对象搭配使用

LineNumberInputStream

记录输入流中的行号,可以调用getLineNumber()和setLineNumber(int)

只是增加了行号而已,因此可能需要与借口对象搭配使用

PushbackInputStream

包含一个单字节回退缓冲区,用于将最后读取的字符推回输入流

通常用于编译器的扫描器,一般不会用到

各种FilterOutputStream类型:

功能

使用方法

DataOutputStream

与DataInputStream搭配使用没这样就能以可移植的方式向流中写入基本类型

包含用于写入基本类型数据的全部接口

PrintStream

用于生成格式化的输出。DataOutputStream负责处理数据的存储,而PrintStream则负责处理数据的显示

应该作为OutputStream对象的最终包装,可能会经常用到

BufferedOutputStream

用来防止在每次发送数据的时候都发生物理写操作,相当于声明使用缓冲,可以调用flush方法来清空缓冲区

本质上并未提供借口,只是为进程增加缓冲操作而已,需要与借口对象搭配使用

独立的RandomAccessFile:

RandomAccesssFile适合用来处理由大小已知的记录组成的文件,由此可以通过seek方法在各条记录上来回移动,然后读取或者修改记录。文件中各条记录的大小不必相同,只需确定它们的大小以及在文件中的位置即可。

它是一个从零实现的、完全独立的类、有着完全属于自己、大部分是原生的方法,其行为和其他IO类型有本质上的区别。

IO流用法:

  • 缓冲输入文件,BufferdReader
  • 从内存输入,StringReader
  • 格式化的内存输入
  • 基本的文件输出
  • 存储和恢复数据
  • 读写随机访问文件

标准IO:

程序的所有输入都可以来自标准输入,所有输出都可以发送到标准输出,所有错误都可以发送到标准错误。

一个程序的标准输出可以称为另一个程序的标准输入。

新IO系统:

新IO库的目标只有一个:速度。

速度的提升来自于其所使用的更接近于操作系统的IO实现方式的结构:通道和缓冲区。

通道其实很简单:向其传入一个用于读写的Bytebuffer,然后锁住问区域以保证独占式访问。

FileChannel类,在旧IO系统中的类通过getChannel方法得到。

public class IOTest {

    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        try {
            FileInputStream inputStream = new FileInputStream("");
           FileChannel channel =  inputStream.getChannel();
           channel.read(byteBuffer);

           channel.write(byteBuffer);
           channel.lock();
           channel.tryLock();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

一旦调用了通道的read方法,就必须在缓冲区上调用flip方法,使缓冲区做好提取字节的准备。并且如果要用缓冲区来做进一步的read操作,就同样需要调用clear方法来让缓冲区为后续的每次read做好准备。

缓冲区中保存着简单的字节,为了将这些字节转换为字符,要么将字节放入的时候进行编码,要么在将他们从缓冲区中读取出来的时候进行解码。

ByteBuffer是由一个8字节的数组包装而成的,随后通过各种不同基本类型的师徒缓冲区将该数组显示出来。

字节序:不同的机器可以使用不同的字节排序方式保存数据。高位优先的方式将最高位的字节放在最低的内存地址,即内存起始地址。低位优先方式将最高位的字节放在最高的内存地址,即内存末尾地址。

内存映射文件:可以创建和修改那些因为太大而无法加载到内存中的文件。

通过在FileChannel上调用tryLock或lock,便可以获得整个文件上的FileLock。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值