1.Java的IO流使用了一种装饰器设计模式,它将IO流分成底层节点流和上层处理流,其中底层节点流用于和底层的物理存储节点直接关联——不同的物理节点获取节点流的方式可能存在差异,但程序可以把不同的物理节点流包装成统一的处理流,从而允许程序使用统一的输入、输出代码来读取不同的物理存储节点资源。
2.File类
File类是java.io包下代表与平台无关的文件和目录,如果希望在程序中操作文件和目录,都可以通过File类来完成,File能创建、删除、重命名文件和目录,但是File不能访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流。
3.流的分类
输入流:只能从中读取数据,而不能向其写入数据。
输出流:只能向其写入数据,而不能从中读取数据。
输入/输出都是从程序运行所在内存的角度划分的。
Java的输入流只要是由InputStream和Reader作为基类,输出流由OutputStream和Writer作为基类。
4.字节流和字符流
字节流操作的数据单元是8位的字节,而字符流操作以的数据单元是16位的字符。
字节流主要是由InputStream和OutputStream作为基类,而字符流主要是由Reader和Writer作为基类。
输入流InputStream和Reader
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
public class InputStreamTest {
public static void main(String[] args) throws IOException {
//字节流
FileInputStream fileInputStream =null;
try {
fileInputStream= new FileInputStream("InputStreamTest.java");
byte[] buff=new byte[1024];
//用于保存实际读取到的字节数
int hasReadCount=0;
while((hasReadCount=fileInputStream.read(buff))>0){
System.out.println(new String(buff,0,hasReadCount));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fileInputStream!=null)fileInputStream.close();
}
//字符流
try(FileReader fr=new FileReader("InputStreamTest.java")){
char[] cbuf=new char[32];
//用于保存实际读取到的字符数
int hasReadCount=0;
while((hasReadCount=fr.read(cbuf))>0){
System.out.println(new String(cbuf,0,hasReadCount));
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
输出流OutputStream和Writer
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputStreamTest {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream=null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream("InputStreamTest.java");
fileOutputStream = new FileOutputStream("newFile.txt");
byte[] buff=new byte[1024];
//用于保存实际读取到的字节数
int hasReadCount=0;
while((hasReadCount=fileInputStream.read(buff))>0){
fileOutputStream.write(buff, 0, hasReadCount);
System.out.println(new String(buff,0,hasReadCount));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fileInputStream!=null)fileInputStream.close();
if(fileOutputStream!=null)fileOutputStream.close();
}
}
}
程序中打开的IO资源不属于内存中的资源,垃圾回收机制无法回收该资源,所以应该显式关闭IO资源,Java 7改写了所有的IO资源类,它们实现了AutoCloseable接口,因此可以通过自动关闭资源的try语句来关闭这些IO流。
5.如果进行输入/输出的内容是文本内容,则应该考虑使用字符流;如果输入/输出的内容是二进制内容,则应该是字节流。计算机的文件常分为文本文件和二进制文件——所有能用记事本打开并看到其中字符内容的文件称为文本文件。
6.转换流
输入/输出体系中还提供了两个转换流,字节流转换成字符流,InputStreamReader将字节输入流转换成字符输入流,OutputStreamWrite将字节输出流转换成字符输出流,Java并没有提供将字符流转换成字节流的方法,因为没必要。