java i o 这本书_Java I/O

Java I/O是Java中很重要的组成部分

一.以字节为向导的Stream InputStream/OutputStream

Java I/O最基本的概念就是输入流与输出流,即InputStream(输入流)和OutputStream(输出流)

InputStream

最基本的字节输入流,抽象类,定义了读取原始字节的所有基本方法

read() 读取一个字节的方法

close() 关闭stream方法,这个是每次在用完流之后必须调用的方法。

available() 返回stream中的可读字节数,inputstream类中的这个方法始终返回的是0,这个方法需要子类去实现。

skip(long n) 从stream中跳过long类型参数个位置

read(byte b[]) 一次性读取内容到缓冲字节数组

read(byte b[],int off,int len) 从数据流中的哪个位置offset开始读长度为len的内容到缓冲字节数组

下面还有三个方法:

mark(int readlimit) 用于标记stream的作用

markSupported() 返回的是boolean类型,因为不是所有的stream都可以调用mark方法的,这个方法就是用来判断stream是否可以调用mark方法和reset方法

reset() 这个方法和mark方法一起使用的,让stream回到mark的位置。

OutputStream

最基本的字节输出流,抽象类,定义了读取原始字节的所有基本方法

write(int b) 写入一个字节到stream中

close() 关闭流,这个是在操作完stream之后必须要调用的方法

flush() 这个方法是用来刷新stream中的数据,让缓冲区中的数据强制的输出

write(byte b[]) 写入一个byte数组到stream中

write(byte b[], int off, int len) 把byte数组中从offset开始处写入长度为len的数据

总结

InputStream和OutputStream定义了I/O领域最基础的行为,也就是读取和写入一个字节,同时使用了模板方法将读取和写入的行为进行了适当扩展。

扩展一:对I/O流的继承

InputStream和OutputStream都是抽象类,它们仅仅定义了I/O领域最基础的方法,但不涉及具体实现。针对不同的数据来源,InputStream和OutputStream存在三种实现:一种是基于内存的ByteArrayInputStream/ByteArrayOutputStream,一种是基于磁盘文件的FileInputStream/FileOutputStream,还有一种是基于网络的SocketInputStream/SocketOutputStream。

FileInputStream/FileOutputStream

读取写入的源是操作系统的文件使用native方法进行底层文件的读取

try

{

//使用FileInputStream和FileOutputStream进行文件复制

FileInputStream fis=new FileInputStream("a.txt");

FileOutputStream fos=new FileOutputStream("b.txt");

int read;

//read=fis.read();

byte b[]=new byte[1024];

//读取文件,存入字节数组b,返回读取到的字符数,存入read,默认每次将b数组装满

read=fis.read(b);

while(read!=-1)

{

fos.write(b,0,read);

read=fis.read(b);

//read=fis.read();

}

fis.close();

fos.close();

}

catch (IOException e)

{

e.printStackTrace();

}

ByteArrayInputStream/ByteArrayOutputStream

读取写入的源是内存的一个数组,比较少见

SocketInputStream/SocketOutputStream

读取写入远程服务器的数据流使用native方法进行底层文件的读取

除上述3种以外还有别的实现如下

StringBufferInputStream/StringBufferOutputStream

据指定串创建一个读取数据的输入流串

PipedInputStream/PipedOutputStream

实现了pipe的概念,主要在线程中使用,管道输入流是指一个通讯管道的接收端。

一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

SequenceInputStream/SequenceOutputStream

把多个In(Out)putStream合并为一个In(Out)putStream,“序列输入(出)流”类允许应用程序把几个输入(出)流连续地合并起来,

并且使它们像单个输入(出)流一样出现。每个输入(出)流依次被读取,直到到达该流的末尾。

然后“序列输入(出)流”类关闭这个流并自动地切换到下一个输入(出)流。

扩展二:对I/O流的扩展

FilterInputStream/FilterOutputStream

FilterInputStream是InputStream一个特殊的子类,它内部有一个很重要的变量如下

protected volatile InputStream in;

protected FilterInputStream(InputStream in) {

this.in = in;

}

这说明了FilterInputStream在实例化的时候,要传一个InputStream类的对象进来。

这个类的特殊之处,就是包含了一个InputStream,使得可以在这个InputStream基础上进行多种封装,从而达到装饰的目的。

这个类本身作用不大,但是他的子类比较有作用

DataInputStream/DataOutputStream

这两个类继承了FilterInputStream/FilterOutputStream,用来实现将java基本类型转换成二进制来进行读写操作,readInt,readFloat,readDouble...这样可以直接从stream中读取基本类型的数据

BufferedInputStream/BufferedOutputStream

继承了FilterInputStream,实现了输入流处理中的缓冲的功能。底层的流会先被读取到一个字节数组中,用户使用BufferedInputStream读取数据的时候,会先读取字节数组中的数据,读完了才会调用底层的流进行进一步的读取。这种方法可以提升读取的性能。继承了FilterOutputStream,实现了输出流处理中的缓冲功能。当用户写入数据的时候,其实是先写入到BufferedOutputStream的一个字节数组中,当这个字节数组满了,才会真正调用底层的输出流执行输出动作。这种方法可以提升写入的性能。在使用BufferedOutputStream的写入功能时,一定要使用flush,因为缓冲数组不满的时候是不会写入底层流的,在写入最后一点数据的时候,缓冲数据不一定被填满,这时候就需要调用flush进行强制刷新。

PrintStream

继承FilterOutputStream,这个类的print和println方法可以把java的一些基本类型数据转换成字节写入到底层输出流,但是PrintStream对String的转换是平台相关的,不同的平台会有不同的编码,所以写入到底层的字节也不同,因此PrintStream只适合于测试输出,不适合于一般的I/O操作,特别是网络流。

PushbackInputStream

继承了FilterInputStream,提供了一种回退的机制,可以实现unread,本质是使用缓冲数组实现了,也就是说,回退的范围是有限的。

二.以字符为向导的Stream Reader/Writer

InputStream和OutputStream是面向字节的,而人类的习惯是面向字符,因此InputStream和OutputStream对于程序猿的用户体验不是太好,于是就需要提供一些面向字符的流。由于DataInputStream/DataOutputStream在跨平台的情况下存在问题,因此,java设计者干脆仿照InputStream和OutputStream重新设计了一套面向字符的I/O,也就是Reader/Writer

Reader

基本的字符输入流,是个抽象类

方法与InputStream对应

Writer

基本的字符输出流,是个抽象类

方法与OutputStream对应

扩展一:对I/O流的继承

CharArrayReader/CharArrayWriter

与前面ByteArrayInputStream/ByteArrayOutputStream对应

StringReader/StringWriter

与前面StringBufferInputStream/StringBufferOutputStream对应

FileReader/FileWriter

与前面FileInputStream/FileOutputStream对应

PipedReader/PipedWriter

与前面PipedInputStream/PipedOutputStream对应

扩展二:对I/O流的扩展

FilterReader/FilterWriter

BufferedReader/BufferedWriter

PushbackReader

PrintWriter

三.两种不同导向的Stream之间的转换

由于计算机只识别字节,所以Reader/Writer的数据来源最终还是字节,而他们无法直接和字节打交道,这时候就需要一个中介者将Reader/Writer和InputStream和OutputStream进行打通,于是就有了InputStreamReader和OutputStreamWriter

InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。

使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。

InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。

为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

![](/Users/admin/Documents/Life/I:O/3400180-bce9503f7c9ee657.png =500x300)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值