在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File,InputStream,OutputStream,Reader,Writer,分别用来进行文件操作,输入输出字节流,输入输出字符流操作,一个接口指的是Serializable,用来将对象进行序列化,然后使用ObjectInputStream/ObjectOutputStream对象输入输出流进行读写。
一java.io包中流的分类:
按照数据流方向的不同可以分为输入流和输出流。
按照按照数据处理单位的不同可以分为字节流和字符流。
因此两两组合供四种情况,如下所示:
其中,InputStream是所有输入字节流的基类,Reader是所有输入字符流的基类,OutputStream是所有输出字节流的基类,Writer是所有输出字符流的基类。其中字节流可用来处理任何类型的数据,如文本,图片,视频,音乐,而字符流一般用来处理文本,尤其是像中文这样的宽字节语言。
二各种IO详解
1 InputStream:为字节输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是向程序中输入数据。
常用的方法:
public int read()
读取一个字节,以整数形式返回
如果读取到输入流的末尾则返回-1
public int read(byte[] buffer)
从输入流中读取一定数量的字节,将其存储在缓冲数组buffer中,以整数形式返回实际读取到的字节数
如果读取到输入流的末尾则返回-1
public int read(byte[] buffer,int off,int len)
从输入流中最多读取len各字节存放到buffer数组中
off表示将读取到第一个字节的数据存储到buffer[off]处,即在buffer数组中存放数据的起始位置
该函数尝试读取len各字节的数据,但可能读取到的数据小于len,以整数形式返回实际读取到的字节数
如果读取到输入流的末尾则返回-1
其类的继承体系如下:
其中重点掌握FileInputStream,BufferInputStream,ByteArrayInputStream,ObjectInputStream
FileInputStream:先来看看它的构造器:
(1)FileInputStream(File fileName) 创建一个输入文件流,从指定的 File 对象读取数据。
(2)FileInputStream(FileDescriptor fdName) 创建一个输入文件流,从指定的文件描述器读取数据。
(3)-FileInputStream(String name) 创建一个输入文件流,从指定名称的文件读取数据。
FileInputStream通常用作文件与其它装饰流之间转换的桥梁,因为装饰流的的构造器的参数一般为InputStream,而FileInputStream为InputStream的子类且其构造器的参数一般为File。
ByteArrayInputStream:把内存中的一个缓冲区作为 InputStream 使用 .
先来看看它的构造器:
(1)ByteArrayInputStream(byte[]) 创建一个新字节数组输入流( ByteArrayInputStream ),它从指定字节数组中读取数据( 使用 byte 作为其缓冲区数组)
(2)ByteArrayInputStream(byte[], int, int) 创建一个新字节数组输入流,它从指定字节数组中读取数据。
正因为ByteArrayInputStream是把内存中的一个缓冲区用作inputStream,所以常用来用作内存缓冲,如在安卓中常常用来解析一个BitMap图片,代码如下:
private Bitmap decodeBitmap(Bitmap bitmap) { int scale = 100; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, scale, bos); while ((bos.toByteArray().length / 1024) > 30) { bos.reset(); bitmap.compress(Bitmap.CompressFormat.JPEG, scale, bos); scale -= 10; } ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); bitmap = BitmapFactory.decodeStream(bis); return bitmap; }
BufferInputStream:
ObjectInputStream:
先来看看它的构造器:
(1)ObjectInputStream():实例化一个ObjectInputStream对象
(2)ObjectInputStream(InputStream):使用一个InputStream对象来实例化一个ObjectInputStream对象,其中InputStream就是对象的输入流
通常我们使用第二个构造器,用来将一个InputStream包裹为ObjectInputStream,最常用的方式就是在网络中传输对象的时候,让某个对象实现Serializable接口,然后就可以用ObjectInputStream的readObject()从网络中读取该对象
2 .OutputStream:为字节输出流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输出流的所有类的超类。 继承自InputStream 的流都是从程序中输出数据。
常用的方法:
public void write(int buffer) 向输出流中写入一个字节的数据
public void write(byte[] buffer)将字节型数组buffer中的数据写入到输出流中
public void read(byte[] buffer,int off,int len)将字节型数组buffer从指定位置off开始的len个字节数据写入到输出流中
其类的继承体系如下:
其中重点掌握FileoutputStream,BufferOutputStream,ObjectoutputStream
FileoutputStream:
BufferOutputStream:
ObjectoutputStream:
以上三种类的所有用法与其对应的InputStream完全相同,只不过将read该为了write。
3Reader:为字符输入流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字符输入流的所有类的超类。 继承自Reader的流都是从源中读取数据。其类的继承体系如下:其中重点掌握BufferedReader:
先来看看它的构造器:
(1)BufferedReader(Reader in):实例化一个ObjectInputStream对象
(2))BufferedReader(Reader in,int size):BufferReader提供了readLine()方法用于从原源中去读一行字符串
通常用作装饰流,将一个InputStreamReader转换为BufferReader,如在安卓中我们通常会用到该类从网络中获取的数据以字符串的形式保存起来,代码如下:
public static void doGetRequest(final String uri,final HttpCallbackListener listener) throws IOException { new Thread(){ public void run () { URL url; try { url = new URL(uri); HttpURLConnection connection=(HttpURLConnection) url.openConnection(); // connection.setDoInput(true); // connection.setRequestMethod("GET"); connection.connect();//必须加上该语句 InputStream is=connection.getInputStream(); BufferedReader reader=new BufferedReader(new InputStreamReader(is));//使用BufferedReader从网络中读取字符串 StringBuilder buffer=new StringBuilder(); String line; while((line=reader.readLine())!=null) { buffer.append(line); } if(listener!=null) { listener.onComplete(buffer.toString()); } } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); }
InputStreamReader:通常与BufferReader联合使用,具体使用情况如上BufferReader所示。
4Writer:为字符输出流,它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字符输出流的所有类的超类。 继承自Writer的流都是向目的地写入数据。其类的继承体系如下:(注意下图,第三个应该为OutputStreamWriter)
其中重点掌握BufferedWriter:
OutputStreamWriter
以上两个类的所有用法与其对应的Reader完全相同,只不过将read改为了write,因此不再赘述。