先来介绍一下I/O流的一些基本概念
根据流的方向,可以分为 :
输入流:程序读数据
输出流:程序写数据
根据流的单位,可以分为:
字节流:一个字节一个字节的流,八位 对应抽象类:InputStream OutputStream
字符流:一个字符一个字符的流,十六位 对应抽象类:Reader Writer
根据流的用途,可以分为:
处理流:套在其他流之上的流,处理数据的流。
节点流:流直接连接源,源包括文件、内存中的数组或字符串、管道。
一、字节流:带stream的都为字节流
二、字符流 :带reader或writer的都为字符流
三、 缓冲流:处理流的一种,套在节点流上面,在内存中的一块空间,缓冲节点流数据,减少I/O读写次数,延长硬盘寿命,带Buffered的都为缓冲流
下面程序是个缓冲流的例子,粗的管道相当于缓冲流,套在细的字节流外面处理数据
四、转换流,处理流的一种。可以将字节数据转换成字符数据。
下面看转换流的例子:
- new FileOutputStream时,参数传了一个true,表示写的时候是向这个文件后追加内容,而不是覆盖。
- 转换流可以指定编码集合。
- 在写入字节流时用转换流包装一下,write()方法就可以传入字符串了,提高写入效率。
再看一个例子,这里的System.in返回的是InputStream抽象类型的流,这个方向相当于读取键盘的输出,然后外层套了一个InputStreamReader转换流,将其由字节流转为字符流,紧接着,外面又套了一个BufferedReader缓冲流,将读取结果放到
一个缓冲区里,然后一行一行的读(readLine()方法是缓冲流的专属方法),这样又快又不损害硬盘
五、数据流,也是处理流的一种。可以将一些java基本数据类型的流或者utf8编码进行I/O操作,而不用去考虑字节字符转换等问题。
看一个例子:
- 首先,ByteArrayOutputStream字节数组输出流在内存中创建一个字节数组,所有发送到输出流的数据保存在该字节数组中,若构造时不带参数,则这个字节数组长度是32,即可以存放32个字节。
- 然后然后将处理流DataOutputStream包在这个字节数组流外面,这样写操作时就不用关心数值类型了
- writeDouble() ,writeBoolean()是写数据的方法,每次调用,相当于依数组下标从小到大将数值放进数组中的单元内,因double型占用超过1个字节,因此需要先转换成long型,然后再放入字节数组,因long占8个字节,因此需要占用数组8个单元。boolean占一个字节。
- ByteArrayInputStream的available()方法:返回字节数组中存有元素的有效长度,因之前放了一个double,又放了一个boolean,总共占了九个字节。因此available()返回9
- DataInputStream的readDouble()和 readBoolean()方法需要注意调用顺序,这个数组相当于一个队列,先进先出,因此先读到的是double类型的。
六、Print流 ,处理流的一种。因为其涉及到的都是打印,输出等操作,因此没有输入流的相关处理类。
看一个例子:
- 写一个文件,使用PrintStream()打印字节流包在FileOutputStream外面,这样可以重新指定print操作
- System.out 这个字段先解释一下,这是 “标准”输出流。 此流已经打开并准备好接受输出数据。 通常,此流对应于显示输出或由主机环境或用户指定的另一个输出目标。
- System.setOut(ps) ;//这里是将system.out.由原来的显示输出改为这个已经套在FileOutputStream之外的PrintStream打印流,换言之,就是这个输出流将流向最终的log.dat文件,因此后面再调用System.out.print()方法时,实际上是执行的PrintStream的print方法,将结果打印在其指定的流中。
这是运行结果
再来一个例子
- 这里是想将键盘输入的内容输出到一个文件中。
- 输入的内容首先读取后用缓冲流管道包一下
- 然后开启一个FileWriter字符流,准备好写入流管道
- 在写入流管道外再包一个打印写入流管道,管道时刻准备中
- 开始从缓冲区读,每读一行,只要不是exit这个字符串,就用打印流写入文件中
七.Object流,Object数据在内存中整个序列化进行I/O操作,因此类需要声明实现了serializable接口
下面看一个例子:
下面再来两个例子:
public static void main(String args[]) throws Exception{
File contentFile = null;
FileInputStream fis = null;
InputStreamReader isr = null;
try {
contentFile = new File("src/cn/duoduo/ddd.txt");
if(contentFile.exists()) {
fis = new FileInputStream(contentFile);
StringBuffer sb = new StringBuffer(8192);
isr = new InputStreamReader(fis, "utf-8");
char buff[] = new char[4096];
int length;
while ((length = isr.read(buff, 0, 4096)) != -1) {
if (length > 0) {
sb.append(buff, 0, length);
}
}
System.out.println(sb.toString());
}
} catch(FileNotFoundException e){
e.printStackTrace();
}finally {
isr.close() ;
fis.close() ;
}
}
下面是一个复制文件的例子:
public static void main(String args[]) throws java.io.FileNotFoundException,IOException {
try(
FileInputStream input = new FileInputStream("src/cn/duoduo/ddd.txt");
FileOutputStream output = new FileOutputStream("src/cn/duoduo/bbb.txt");
BufferedInputStream bfInput = new BufferedInputStream(input);
BufferedOutputStream bfOutput = new BufferedOutputStream(output);
) {
int r, bytesNumber = 0;
while ((r = bfInput.read()) != -1) {
bfOutput.write(r);
bytesNumber++;
}
System.out.println("Destination.java有"+bytesNumber+"个字节");
}
}