java基础知识I/O流使用详解
“流”概念源于unix中的管道(pipe)的概念。在unix中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等,它屏蔽了实际的i/o设备中处理数据的细节。 一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是internet上的某个url。 流的方向是重要的,根据流的方向,流可以分为两类:输入流和输出流。其实输入/输出是想对于内存来说的。实际上,流的源端和目的端可简单地看成是字节的生产者和消费者,对于输入流,可不必关心它的源端是什么,只要简单地从流中读数据,而对输出流,也可不知道它的目的端,只是简单地往流中写数据。
a.流:一组有序的数据序列。
b字节流:数据流中最小的数据单元是字节。
c.字符流:数据流中最小的数据单元是字符。
一. java.io包中的类对应两类流
一类流直接从指定的位置(如磁盘文件或内存区域)读或写,这类流称为结点流,其他的流则称为过滤流(包装流)
过滤流:一些流可以从文件以及其他地方接收字节,另一些流可以将字节组合成更有用的数据类型。将一个已经存在的流传递给另一个流的构造方法,将这两种流结合起来,结合后的流被称为过滤流。过滤器输入流往往是以其它输入流作为它的输入源,经过过滤或处理后再以新的输入流的形式提供给用户,过滤器输出流也类似。我们很少用单一的类来创建流对象,而是通过叠合多个对象来提供所期望的功能(即装饰器设计模式)。
java的常用输入、输出流其实都是继承自4个抽象类,分别是:
基于单字节的inputstream,outputstream类(面向字节形式的i/o)
基于双字节的unicode代码单元的 reader, writer类(面向字符形式的i/o)
一旦打开输入流后,程序就可从输入流串行地读数据。从输入流读/写数据的过程一般如下:打开一个流通道-->读取/写信息-->关闭流通道。
在java平台中,有以下两种方式能获得本地平台的字符编码类型:
(a)system.getproperty("file.encoding");
(b) charset cs=charset.defaultcharset();
所有的输入流、输出流都可以分为字节(输入、输出)流,字符(输入、输出)流,处理字节的主要是(outputstream/inputstream) 系列,处理字符的,主要是(reader/write)系列
二.以字节(byte)为导向的输入流(inputstream系列),这几个类都可以与fileinputstream对象相连以提供有用接口:
bytearrayinputstream:把内存中的一个缓冲区作为inputstream使用
stringbufferinputstream(在java1.1中已经弃用了):把一个string对象作为inputstream,底层实现使用stringbuffer
fileinputstream:把一个文件作为inputstream,实现对文件的读取操作(文件名、文件、filedescriptor对象)
pipedinputstream:实现了pipe的概念,主要在线程中使用(作为多进程中的数据源)
sequenceinputstream:把多个inputstream合并为一个inputstream
以字节(byte)为导向的输出流(outputstream系列),可以与filteroutputstream对象相连以提供有用接口:
bytearrayoutputstream:在内存中创建缓冲区,把信息存入内存中的一个缓冲区中,缓冲区初始化尺寸(可选)
fileoutputstream:把信息存入文件中(文件名、文件、filedescriptor)
pipedoutputstream:实现了pipe的概念,主要在线程中使用(指定用于多线程的数据的目的地)
三.与之对应的(reader/writer)系列:
reader: 与inputstream相对应,适配器inputstreamreader
writer: 与outputstream相对应,适配器为outputstreamwriter
filereader: 与fileoutputstream相对应
filewriter: 与fileourputstream相对应
stringreader: 无相对应的类
stringwriter: 与bytearrayinputstream相对应
chararrayreader: 与bytearrayoutputstream相对应
chararraywriter: 与bytearrayoutputstream相对应
pipedreader: 与pipedinputstream相对应
pipedwriter: 与pipedoutputstream相对应
四.两种不限导向的stream之间的转换(使用适配器类)
inputstreamreader和outputstreamreader:把一个以字节为导向的stream转换成一个以字符为导向的stream。
inputstreamreader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集
outputstreamwriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集
五.通过filterinputstream从inputstream读取数据:
datainputstream:从stream中读取基本类型(int、char,long等)数据。
bufferedinputstream:使用缓冲区 ,使用它可以防止每次读取都得进行实际的读操作
linenumberinputstream:会记录input stream内的行数,然后可调用getlinenumber()和setlinenumber(int)
pushbackinputstream:很少用到,一般用于编译器开发
通过filteroutputstream向outputstream写入:
dataioutputstream:可以按照移植方式往stream中输出基本类型(int、char,long等)数据。
bufferedoutputstream:使用缓冲区 ,使用它可避免每次发送数据都进行实际的写操作
printstream:产生格式化输出 ,其中dataoutputstream处理数据的存储,printstream处理显示
六.更改流的行为
尽管bufferedoutputstream是filteroutputstream的子类,但是bufferedwriter并不是filterwriter的子类,(filterwriter是抽象类,没有任何子类)
没有与datainputstream对应的类。除非在要使用readline()时改用bufferedreader,否则使用datainputstream
bufferedreader:与bufferedinputstream对应
linenumberreader:与linenumberinputstream对应
pushbackreader:与pushbackinputstream对应
bufferedwrite:与bufferedoutstream对应
printwrite:与 printstream对应
七.自我独立的类:randomaccessfile
这个类适用于有大小已知的记录组成的文件,randomaccessfile除了实现了datainput和dataoutput接口(datainputstream和dataoutputstream也实现了这两个接口)之外,这个类是个完全独立的类,它拥有和别的i/o类型本质不同的行为,可以在一个文件内向前和向后移动,直接从object派生而来。
可通过randomaccessfile对象完成对文件的读写操作
在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写
可以直接跳到文件中指定的位置
randomaccessfile的大部分功能(不是全部)有nio存储映射文件所取代