---------------------- android培训、java培训、期待与您交流! ----------------------
IO体系结构
字符流
Writer
|--BufferedWriter
|--CharArrayWriter
|--StringWriter
|--OutputStreamWriter
|--FileWriter
|--PrintWriter
Reader
|--BufferedReader:
|--LineNumberReader
|--CharArrayReader
|--StringReader
|--InputStreamReaer
|--FileReader
字节流:
InputStream
|--FileInputStream:
|--FilterInputStream
|--BufferedInputStream
|--DataInputStream
|--ByteArrayInputStream
|--ObjectInputStream
|--SequenceInputStream
|--PipedInputStream
OutputStream
|--FileOutputStream
|--FilterOutputStream
|--BufferedOutputStream
|--DataOutputStream
|--ByteArrayOutputStream
|--ObjectOutputStream
|--PipedOutputStream
|--PrintStream
不是流体系中的,RandomAccessFile:
Io流是用来处理设备直接的数据的。
按流向分为输入流InputStream,输出流。OutputStream.
按流操作数据分为字节流(Reader输入,Writer输出),字符流。
其实早期就只有字节流,因为计算机数据的单位就是字节。后来为什么出现了字节流呢?
因为每个国家都编制了自己的文字编码表。这样编码表就有了不确定性。为了操作文本数据方便,我们将(字节流和编码边)封装起来就有了字符流。
自定义缓冲区MyBufferedReader
缓冲区原理:自定义缓冲区
package cn.itcast.io.p5.mybuffer;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/*
* 缓冲区的模拟。
*/
public class MyBufferedReader extends Reader{
/*
* 1,这个类中一定要有一个字符数组。
* 2,必须要有一个可以操作数组的角标。
* 3,还要对外提供一个获取数据的方法。myRead.
* 4,希望提供一个可以一次获取一行数据的方法,myReadLine.
* 5,缓冲区一创建一定要流,通过构造函数来完成。
*/
private char[] buffer = new char[1024];
private int pos = 0;//用于操作数组的指针(角标)。
//定义计数器记录住缓冲区中元素个数。
private int count = 0;
private Reader r;
//在构造是接收一个被缓冲的流对象。
public MyBufferedReader(Reader r){
this.r = r;
}
/**
* 提供一个读取一个字符方法。
* @throws IOException
*
*/
public int myRead() throws IOException{
/*
* 思路:
* 1,应该借助具体的流对象的read方法从源中获取数据存储到该缓冲区中数组。
* 2,通过角标从数组中获取一个字符。
*/
if(count==0){
//1,读取数据到数组。
count = r.read(buffer);
//取一次数据,要将角标归零。
pos = 0;
}
if(count<0)
return -1;
char ch = buffer[pos];
pos++;
count--;
return ch;
}
/**
* 提供一个一次读取一行的方法。
* @throws IOException
*/
public String myReadLine() throws IOException{
/*
* 思路:
* 1,从缓冲区中读取单个字符数据,
* 存储到指定的容器中,在存储时要进行判断,是否是行终止符,如果是,将存储的数据变成字符串返回。
*
*/
//1, 定义容器。
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=myRead())!=-1){
if(ch=='\r'){
continue;
}
if(ch=='\n'){
return sb.toString();
}
sb.append((char)ch);
}
if(sb.length()!=0){
return sb.toString();
}
return null;
}
/**
* 关闭缓冲区。
*/
public void myClose()throws IOException{
// 其实关闭就是被缓冲的流。
r.close();
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
return 0;
}
@Override
public void close() throws IOException {
}
}
IO中的其他类
一:打印流.
PrintStream(字节打印流)与printWritre(字符打印流)
PrintStream
构造方法可以接受三种表现形式
1,字节输出流,2File对象,3字符串路径
字节打印流的特点:1提供了更丰富的内容
2该流不抛IO异常
3方便打印数据的表现形式
字节流中的write方法write(int b)写的是一个整数话,写入的是它二进制表现形式的最低的一个字节.它里面的print方法print(int b)打印的是该整数的字符串表现形式,原理是将该整数转换成字符串.如果不改变该整数的值与大小应用printInt(int b)方法.
printWritre>>>>>>>比较常用的流
构造方法:1File对象2字节输出流3字符输出流4字符串路径
对于直接操作文件可以指定字符集(编码表)。
凡是接收输出流参数的都可以指定boolean参数完成自动刷新。
二序列流(sequenceInputStream)
序列流的原理:内部存在一个集合存储这些读取流.就是操作多个读取流,可以实现数据合并功能
构造方法可以传入两个读取流或者一个枚举(枚举里面装的都是读取流对象)
枚举的获得1:首先创建Vector集合.通过该集合可以拿到枚举
2:创建ArrayList集合.创建一个匿名内部类枚举子类接口对象,那怎么实现hasElements,因为枚举接口和迭代接口是功能重复的.创建ArrayList迭代器,因为内部类要用到迭代器所以迭代器必须被Final修饰.
3:可以通过Collections里面的enumetion()方法获得枚举,传进去一个集合就返回一个枚举.
三对象的序列化和反序列化
ObjectOutputStream(序列化)ObjectInputStream(反序列化)
序列化:操作对象的流,将内存中的对象持久化到外部设备中,使用的是writeObject()传入一个对象.
反序列化:读取存储对象的文件.为了操作对象方便,.使用的方法是readObject()返回类型是该对象.
构造方法可以传入相应的OutputStream和InputStream.
注意事项:怎么才是序列化了呢?该对象实现Serializable接口,否则会出现NottSerializbleException异常.实现了这个接口会给该对象一个唯一UID号.如果对象内容变化了会出异常,因为UID号改变了.这里建议在对象中手动给出UID号.private static final long serialVersionUID = 18L;
---------------------- android培训、 java培训、期待与您交流! ----------------------