java io的流式部分
参考链接:http://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html
http://blog.csdn.net/wwww1988600/article/details/8835813?utm_source=tuicool&utm_medium=referral
一.io流的介绍:
流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流(即输入流),这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流(输出流)。
二.io流的四个基本类:
java.io包中包含了流式I/O所需要的所有类。在java.io包中有四个基本类:InputStream、OutputStream及Reader、Writer类,它们分别处理字节流和字符流:
2.1 io流类图结构:
2.2 io流分类:
流序列中的数据既可以是未经加工的原始二进制数据,也可以是经一定编码处理后符合某种格式规定的特定数据。因此Java中的流分为两种:
1) 字节流:数据流中最小的数据单元是字节。
2) 字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节。
字符与字节的区别与联系:
字节:是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制。
字符:字符是人们使用的记号,抽象意义上的一个符号。
字符通过不同的编码方式(ascii码制)与二进制码进行对应,而8位二进制码即为一个字节
用字符流和字节流处理文件类型的不同:
(1) 文件中显示的是字符,如果将文件作为字节输入流或者输出流的源,那么在读写过程中必然会发生char类型与byte类型的转换,那么java是如何转换的呢?
char是字符类型,java使用的unicode编码,当字符类型与数值类型(如int,byte)的转化是通过unicode编码的对应关系进行转换的。
例如:char a='a';
byte b=(byte)a; // 打印b,输出97;
int t=a; //打印t,输出97;
char c=a+10; //打印c,输出k;
(2)用字符流处理文件时,用char[]数组进行数据的存储,所以不会发生类型转换,
三.Java IO流对象
3.1.输入字节流InputStream:
InputStream 为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是向程序中输入数据的,且数据单位为字节(8bit);
InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:
(1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。若返回值=-1说明没有读取到任何字节读取工作结束。
(2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
(4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
(5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
(6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.
主要的子类(都实现了抽象类的方法):
FileInputStream
把一个文件作为输入流,实现对文件的读取操作
构造方法:
File fin=new File("d:/abc.txt");
FileInputStream in=new FileInputStream( fin);
然后用in调用read方法进行读操作
ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
StringBufferInputStream:把一个String对象作为InputStream
PipedInputStream:实现了pipe的概念,主要在线程中使用
SequenceInputStream:把多个InputStream合并为一个InputStream
Bufferedinputstream:
BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能;BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式(软工设计模式,留坑)。
使用方法:
int SIZE=1024;
byte b[]=new byte[100];
File f=new File("...");
FileInputStream input=new FileInputStream(f);
BufferedInputStream bis=new BufferedInputStream(input,2*SIZE);//指定文件带缓冲区的读取流且指定缓冲区大小为2KB
bis.read(b);//将数据读入b数组
3.2 输出字节流OutputStream
2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
5. public void close( ) : 关闭输出流并释放与流相关的系统资源。
主要的子类:(均实现了以上的方法)
1) FileOutputStream:把信息存入文件中 ,构造器第二个boolean类型的参数:true表示写在文件末尾
2) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
3) PipedOutputStream:实现了pipe的概念,主要在线程中使用
4) SequenceOutputStream:把多个OutStream合并为一个OutStream
5)BufferedOutputStream: 与BufferedIutputStream是一对流,BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。
3.3 字符输入流Reader
Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此,JAVA中引入了处理字符的流。
用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
主要子类:
![](https://img-my.csdn.net/uploads/201204/01/1333250341_6152.gif)
FileReader :字符流处理文件
主要用来读取字符文件,使用缺省的字符编码(unicode)
CharArrayReader:字符流处理字符数组,
StringReader : 字符流处理字符串
InputStreamReader :从输入流读取字节,再将它们转换成字符:Public inputstreamReader(inputstream is);
FilterReader: 用于过滤字符流
BufferReader :接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。
主要方法:
(1) public int read() throws IOException; //读取一个字符,返回值为读取的字符
(2) public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/
(3) public abstract int read(char cbuf[],int off,int len) throws IOException;
/*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/
3.4 字符输出流Writer
写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。 其子类如下:
1)FileWrite: 将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。
Public FileWrite(file f);
2) chararrayWrite: 将字符缓冲器用作输出。
Public CharArrayWrite();
3) PrintWrite: 生成格式化输出,同上printstream。不同的是构造器的传入的是字符流而不是字节流。
public PrintWriter(outputstream os);
4) filterWriter: 用于写入过滤字符流
protected FilterWriter(Writer w);
5) PipedWriter:处理线程的字符流
6) StringWriter:无与之对应的以字节为导向的stream
7) OutputStreamReader: 将输出字节流传入构造器,再将它们转换成字符流:Public outputstreamReader(outputstream is);
主要方法:
(1) public void write(int c) throws IOException; //将整型值c的低16位写入输出流
(2) public void write(char cbuf[]) throws IOException; //将字符数组cbuf[]写入输出流
(3) public abstract void write(char cbuf[],int off,int len) throws IOException; //将字符数组cbuf[]中的从索引为off的位置处开始的len个字符写入输出流
(4) public void write(String str) throws IOException; //将字符串str中的字符写入输出流
(5) public void write(String str,int off,int len) throws IOException; //将字符串str 中从索引off开始处的len个字符写入输出流
(6) flush( ) //刷空输出流,并输出所有被缓存的字节。
(7) close() 关闭流 public abstract void close() throws IOException
* 这个范围内所有的数据, 都有可能在数据中出现
* read()方法需要返回一个特殊的值来表示流末尾, 这个值不能和流中的数据重复
* char的取值范围是从0到65535
* 这个范围内的所有字符, 都有可能在数据中出现
* 我们需要使用一个不可能在数据中出现的值来表示流末尾
* 那么Java中就是用-1来表示这个末尾的, 因为-1不会在数据中出现,而为了返回-1, 那么只能用int
File file=new File("C:/Users/WWWYU/Desktop/test.txt");
FileInputStream fis=new FileInputStream(file);
int t=0;
while((t=fis.read())!=-1){
System.out.print((char)t);
}
File file=new File("C:/Users/WWWYU/Desktop/test.txt");
FileInputStream fis=new FileInputStream(file);
int t=0;
while((t=fis.read())!=-1){
System.out.print((char)t);
}