Java流与文件操作
流操作和文件操作是学习Java过程中最基础的内容,同时也是非常重要的内容。Java流操作和文件操作内容比较复杂,下面我做一些粗糙的整理与总结,所述不确切的以及漏掉的,还望读者积极指正。
流与文件的读写操作
1、流的简单分类:
(1)、处理纯文本文件的字符流
Reader,子类:BufferedReader、FileReader、InputStreamReader
Writer,子类 :BufferedWriter、FileWriter、OutputStreamWriter
(2)、处理任意文件的字节流
InputStream ,子类:FileInputStream、BufferedInputStream
OutputStream,子类:FileOutputStream,BufferedOutputStream
其中 InputStreamReader 和 OutputStreamWriter是字节流向字符流过度的桥梁,非常重要。
2、流的使用实例:
下面简单用几个实例介绍一下这些流的操作步骤:
(1)、从键盘输入内容,保存到文件中
既然是从键盘输入,自然是文本内容,所以用字符流即可。为了耗时较少可以选用带缓冲区的BufferedReader 和 BufferedWriter。但是,键盘输入用的系统输入流System.in是字节流,就需要将此字节流转换成字符流,就要用到 InputStreamReader
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
/*
* 从键盘输入内容,保存到文件中
*/
public class KeyBoardToFile {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bufr=null;
BufferedWriter bufw=null;
try{
bufr=new BufferedReader(new InputStreamReader(System.in));
bufw=new BufferedWriter(new FileWriter("阿房宫赋.txt"));
String str=null;
while((str=bufr.readLine())!=null){
bufw.write(str);
bufw.newLine();
bufw.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally {
bufr.close();
bufw.close();
}
}
}
(2)、复制文件内容到另一个文件中:
既然是复制文件,就分为两类,一类是纯文本文件,可以选用字符流BufferedReader 和 BufferedWriter;另一类是非纯文本文件(如媒体文件),可以选用字节流BufferedInputStream 和 BufferedOutputStream。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
/*
* 复制一个文件的内容到另一个文件
*/
public class FileToFile {
public static void main(String[] args) {
// TODO Auto-generated method stub
File file1=null;
File file2=null;
File file3=null;
File file4=null;
BufferedReader bufr=null;
BufferedWriter bufw=null;
BufferedInputStream bufin=null;
BufferedOutputStream bufout=null;
try {
file1=new File("阿房宫赋.txt");
file2=new File("商业区地图.jpg");
file3=new File("阿房宫赋1.txt");
file4=new File("商业区地图1.jpg");
// 复制文本文件
bufr=new BufferedReader(new FileReader(file1));
bufw=new BufferedWriter(new FileWriter(file3));
String str=null;
while((str=bufr.readLine())!=null){
bufw.write(str);
bufw.newLine();
}
bufw.flush();
// 复制非文本文件
bufin=new BufferedInputStream(new FileInputStream(file2));
bufout=new BufferedOutputStream(new FileOutputStream(file4));
byte[] buf=new byte[1024];
int n=0;
while((n=bufin.read(buf))!=-1){
bufout.write(buf,0,n);
}
bufout.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
try{
bufr.close();
bufw.close();
bufin.close();
bufout.close();
}catch(Exception e1){
e1.printStackTrace();
}
}
}
}
(3)、将文件内容输出到控制台:
既然是输出到控制台,自然是文本文件,可以选用 BufferedReader 和 BufferedWriter。但是,输出到控制台的是字节流,就需要将此字节流转换成字符流,就要用到 OutputStreamWriter
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.OutputStreamWriter;
/*
* 将一个文本文件的内容输出到控制台
*/
public class FileToKeyboard {
public static void main(String[] args) {
// TODO Auto-generated method stub
BufferedReader bufr=null;
BufferedWriter bufw=null;
try {
// 读
bufr=new BufferedReader(new FileReader("阿房宫赋.txt"));
bufw=new BufferedWriter(new OutputStreamWriter(System.out));
String str=null;
while((str=bufr.readLine())!=null){
bufw.write(str);
bufw.newLine();
}
bufw.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
try{
bufr.close();
bufw.close();
}catch(Exception e1){
e1.printStackTrace();
}
}
}
}
3、不同流的性能分析:
不同的应用场景我们需要选择不同的流对象进行处理,并且同一个场景,也有不同的选择(如,是否需要缓冲区),这些看使用的的使用习惯了,但是不同的流性能是不同的(尤其体现在时间效率上),下面就通过文件的不同写方式,分析这各个流的时间性能。
import java.io.*;
public class FileTest {
public FileTest() {
}
public static void main(String[] args) throws IOException {
FileOutputStream out=null;
FileOutputStream out1=null;
BufferedOutputStream bufout=null;
FileWriter fw=null;
BufferedWriter bw=null;
int count=10000;//写文件行数
try{
out=new FileOutputStream("dandan0.txt");
out1=new FileOutputStream("dandan1.txt");
bufout=new BufferedOutputStream(out1);
fw=new FileWriter("dandan2.txt");
bw=new BufferedWriter(new FileWriter("dandan3.txt"));
String str="测试Java 文件操作\r\n";
byte[] bytes=str.getBytes();
// 方式1 字节流方式(无缓冲区)
long begintime0=System.currentTimeMillis();
for(int i=0;i<count;i++){
out.write(bytes);
}
long endtime0=System.currentTimeMillis();
System.out.println("FileOutputStream执行耗时:"+(endtime0-begintime0)+"毫秒");
// 方式1 字节流方式(有缓冲区)
long begintime1=System.currentTimeMillis();
for(int i=0;i<count;i++){
bufout.write(bytes);
}
bufout.flush();
long endtime1=System.currentTimeMillis();
System.out.println("BufferedOutputStream执行耗时:"+(endtime1-begintime1)+"毫秒");
// 方式1 字符流方式(无缓冲区)
long begintime2=System.currentTimeMillis();
for(int i=0;i<count;i++){
fw.write(str);
}
long endtime2=System.currentTimeMillis();
System.out.println("FileWriter执行耗时:"+(endtime2-begintime2)+"毫秒");
// 方式1 字符流方式(带缓冲区)
long begintime3=System.currentTimeMillis();
for(int i=0;i<count;i++){
bw.write(str);
}
bw.flush();
long endtime3=System.currentTimeMillis();
System.out.println("BufferedWriter执行耗时:"+(endtime3-begintime3)+"毫秒");
}catch(Exception e){
e.printStackTrace();
}finally {
out.close();
bufout.close();
bw.close();
out1.close();
fw.close();
}
}
}
程序运行结果:
FileOutputStream执行耗时:24毫秒
BufferedOutputStream执行耗时:2毫秒
FileWriter执行耗时:20毫秒
BufferedWriter执行耗时:3毫秒
从这个结果中可以看出,带缓冲区的字符流和字节流在时间上较不带缓冲区的字符流和字节流有很明显的优势;同时,不带缓冲区的字符流比字节流时间效率要高,而带缓冲区的字符流比字节流时间效率要差。