java IO流可 分为输入流 和 输出流。这里的输入和输出是相对于程序而言的,外部数据输入到程序中时,我们用输入流,程序中的数据输出到外部时,我们用输出流。
输入流又可分为字节输入流和字符输入流。字节输入流的基类为InputStream,我们常用到它的子类FileInputStream, 字符输入流的基类为Reader,我们常用到它的子类FileReader。
输出流又可分为字节输出流和字符输出流。字节输出流的基类为OutputStream,我们常用到它的子类FileOutputStream, 字符输出流的基类为Writer,我们常用到它的子类FileWriter。
那什么时候该用字节流,什么时候该用字符流呢?
一般来说,在输入输出一些二进制对象的时候比如图片,音乐,视频文件,我们用字节流。 在输入输出一些文本文件的时候比如文字,我们用字符流。字符其实可以理解为是字节+对应的编码表(utf-8,gbk等)构成的,相同的一段字节,用不同的编码格式,最后得到的字符是不一样的(生活常见的乱码就是这样产生的)
另外,java在字节流和字符流中间提供了一层吧转换流,,可以将字节流转化为字符流。输入的转换流为InputStreamReader(InputStream is),输出的转换流为OutputStreamReader(OutputStream os )。
解释了这么多,不如用一图来总结一下:
java提供了操作IO流的API,在代码中如何使用呢? 接下来,直接附上几个比较实用的demo,可参考运用到自己的代码里
public class CopyMp3Demo {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
method1("e:\\music.mp3", "copy1.mp3");
method2("e:\\music.mp3", "copy2.mp3");
method3("e:\\music.mp3", "copy3.mp3");
method4("e:\\music.mp3", "copy4.mp3");
long end = System.currentTimeMillis();
System.out.println(" 总共耗时:" + (end - start) + "毫秒");
}
// 基本字节流一次读写一个字节
public static void method1(String src, String dest) throws Exception {
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);
int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
}
fis.close();
fos.close();
}
// 基本字节流一次读写一个字节数组
public static void method2(String src, String dest) throws Exception {
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);
int len = 0;
byte[] bys = new byte[1024];
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
}
fis.close();
fos.close();
}
// 高效字节流一次读写一个字节:
public static void method3(String src, String dest) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}
bis.close();
bos.close();
}
// 高效字节流一次读写一个字节数组:
public static void method4(String src, String dest) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
int len = 0;
byte[] bys = new byte[1024];
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bis.close();
bos.close();
}
}
这里我们的目的是利用IO流将E盘根目录下的music.mp3文件拷贝到项目工程目录下,前面说了,拷贝音乐文件用字节流,这里提供了四种拷贝方式,可以比较拷贝所需时间,其中第一种方式(基本字节流一次读写一个字节 )最慢,第四种(高效字节流一次读写一个字节数组)最快,中间两种差不多。
说一下这里的BufferedInputStream是输入流(对应的输出流BufferedOutputStream)的缓冲流,又称装饰流,一般我们建议在基本流外面包上装饰流,因为这样可极大提升效率。
//字符流读写数据的五种方式
public class CopyTxtDemo {
public static void main(String[] args) throws IOException {
String SrcString = "a.txt";
String DestString = "b.txt";
// method1(SrcString,DestString);
// method3(SrcString,DestString);
// method4(SrcString,DestString);
method5(SrcString, DestString);
}
// 基本字符流一次读写一个字符
private static void method1(String srcString, String destString) throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
int len = 0;
while ((len = fr.read()) != -1) {
fw.write(len);
}
fr.close();
fw.close();
}
// 基本字符流一次读写一个字符数组
private static void method2(String srcString, String destString) throws IOException {
FileReader fr = new FileReader(srcString);
FileWriter fw = new FileWriter(destString);
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
}
fr.close();
fw.close();
}
// 高效字符流一次读写一个字符
private static void method3(String srcString, String destString) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
int len = 0;
while ((len = br.read()) != -1) {
bw.write(len);
}
br.close();
bw.close();
}
// 高效字符流一次读写一个字符数组
private static void method4(String srcString, String destString) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}
br.close();
bw.close();
}
// 高效字符流一次读写一行
private static void method5(String srcString, String destString) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(srcString));
BufferedWriter bw = new BufferedWriter(new FileWriter(destString));
String len = null;
while ((len = br.readLine()) != null) {
bw.write(len);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
上面代码的目的是将项目工程下的“a.txt”文件拷贝到b.txt里。前面说了拷贝文本文件用字符流。前四种拷贝方式就不说了,跟字节流差不多,第五种比较特殊,一次读写一行。
注意:上述代码最好加上try–catch,并在finally里关闭流。如下:
public static void method3(String src, String dest) throws Exception {
BufferedInputStream bis =null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(src));
bos = new BufferedOutputStream(new FileOutputStream(dest));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
bos.close();
bis.close();
}
}