文件的读写是java i/o流常用的也是最基础的操作,然而字节流,字符流,InputStream,OutpurStream,Reader,Writer等等,各种各样的流操作类傻傻分不清楚,今天我们就对常用的流操作做简单的总结。本文力求简洁,不至于看到大量的代码觉得困倦。
字节流/字符流表
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 | |
---|---|---|---|---|---|
抽象基类 | InputStream |
OutputStream |
Reader |
Writer |
|
访问文件 | FileInputStream | FileOutputStream | FileReader | FileWriter | |
访问数组 | ByteArrayInputStream | BiteArrayOutputStream | CharArrayReader | CharArrayWriter | |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter | |
访问字符串 | StringReader | StringWriter | |||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter | |
转换流 | InputStreamReader | OutputStreamWriter | |||
对象流 | ObjectInputStream | ObjectOutputStream | |||
抽象基类 | FilterInputStream |
FilterOutputStream |
FilterReader |
FilterWriter |
|
打印流 | PrintStream | PrintWriter | |||
推回输入流 | PushbackInputStream | PushbackReader | |||
特殊流 | DataInputStream | DataOutputStream |
其中基类都是抽象类,不同的子类对应不同的用途
首先我们看一下字节流与字符流的不同之处
字节流是由字节组成的,字符流是由字符组成的. Java里字符由两个字节组成.字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化。
通俗的来讲,字节流就是二进制流,通常的图片,视频,音频文件都可以通过字节流来读写,字符流就是字符串,中文字符,等unicode字符编码后的字符集。字节流可以通过转换流(即InputStreamReader
,InputStreamWriter
)转换为字符流(转化的过程就是编码的过程),缓冲流是为了提高读写效率提供的类,可以开辟出一个缓冲区用于高速存取数据流(分别对应字节流和字符流)。
字节流读写文件的实例
public class FileCopy {
public void fileCopy(String sourceFile,String targetFile) throws IOException{
FileInputStream in=new FileInputStream(sourceFile);
FileOutputStream out=new FileOutputStream(targetFile);
byte[] buffer=new byte[2048];//创建2048个字节大小的缓冲区(可根据拷贝文件大小自行定义)
int value;
while((value=in.read(buffer))!=-1){//循环读写
out.write(buffer, 0, value);
}
if(in!=null)in.close();//关闭i/o流
if(out!=null)out.close();
}
public static void main(String[] args) throws IOException {
String in="readFile.txt";
String out="outFile.txt";
FileCopy f=new FileCopy();
f.fileCopy(in, out);
}
}
字节流转字符流实例
文件拷贝不推荐用这种方法,此方法仅作为字节流转字符流的实例,因为在文件copy中字节流转化为字符流读写的意义不大,而且会降低运行效率
public class FileCopy {
public void fileCopy(String sourceFile,String targetFile) throws IOException{
FileInputStream in=new FileInputStream(sourceFile);
FileOutputStream out=new FileOutputStream(targetFile);
BufferedReader reader=new BufferedReader(new InputStreamReader(in));
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));
String line="";
StringBuffer result=new StringBuffer();
while((line=reader.readLine())!=null){
writer.write(line);//此处的write是将数据写入缓冲区,并没有写入文件
writer.flush();//将缓冲区数据写入文件
}
if(writer!=null)writer.close();
if(reader!=null)reader.close();
}
public static void main(String[] args) throws IOException {
String in="readFile.txt";
String out="outFile.txt";
FileCopy f=new FileCopy();
f.fileCopy(in, out);
System.out.println("hell java");
}
}
关键在于这两行
BufferedReader reader=new BufferedReader(new InputStreamReader(in));
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));
将FileInputStream作为参数传入InputStreamReader中然后作为参数传给BufferedReader,其中InputStreamReader作为Reader的子类传入