------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
众所周知,在Java中,实现文件复制的方式有很多,并且还要考虑到选用字符流还是字节流
如果仅仅只是文本文件的话,我们使用字符流无可厚非,但不一定所有的文件都是文本文件啊
在视频,音频方面,就要用到字节流的操作了
PS:在使用字符流的过程中,还要注意中文字符的编码问题
Java API中,我们也可以利用文件通道(FileChannel)来实现实现文件的复制,并且在文件越大的时候,用这个复制的效率越高
在这里,为了便于比较,我把三个方法写到了一起,并加入了耗时输出,我们可以通过耗时来比较那种方法最优
/**
* 文件的复制操作——IO操作
* @author Shawn·Zhang
*/
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;
import java.io.IOException;
import java.nio.channels.FileChannel;
public class Example08 {
public static void main(String[] args) throws Exception {
//分别复制两个文件
// E:\\java\\source.txt
// F:\\革命歌曲\\004.mp3 国际歌(合唱版).mp3
byteCopy(new File("E:\\java\\source.txt"), new File(
"C:\\Users\\Z_DELL_PC\\Desktop\\target1.txt"));
charCopy(new File("E:\\java\\source.txt"), new File(
"C:\\Users\\Z_DELL_PC\\Desktop\\target2.txt"));
fileChannelCopy(new File("E:\\java\\source.txt"), new File(
"C:\\Users\\Z_DELL_PC\\Desktop\\target3.txt"));
}
/**
* 字节流复制方法
* @param source 源文件
* @param target 目标文件
*/
private static void byteCopy(File source, File target){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
int len;//定义一个int类型的变量len,记住每次读取的一个字节
try {
bis = new BufferedInputStream(new FileInputStream(source));//创建一个带缓冲区的输入流
bos = new BufferedOutputStream(new FileOutputStream(target));//创建一个带缓冲区的输出流
long begintime = System.currentTimeMillis();//获取拷贝文件前的系统时间
while((len=bis.read())!=-1){//读取一个字节并判断是否读到文件末尾
bos.write(len);//将读到的字节写入文件
}
long endtime = System.currentTimeMillis();//获取拷贝文件后的系统时间
System.out.println("字节流拷贝文件消耗的时间是:" + (endtime - begintime) + "毫秒");//输出耗时
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 字符流复制方法
* @param source 源文件
* @param target 目标文件
*/
private static void charCopy(File source, File target){
BufferedReader br = null;
BufferedWriter bw = null;
String str;
try {
br = new BufferedReader(new FileReader(source));//创建一个bufferedreader缓冲对象
bw = new BufferedWriter(new FileWriter(target));//创建一个bufferedwrite缓冲对象
long begintime = System.currentTimeMillis();
while((str=br.readLine())!=null){//每次读取一行文本,判断是否读到文本末尾
bw.write(str);
bw.newLine();//写入一个换行符,该方法会根据不同的操作系统生成相应的换行符
}
long endtime = System.currentTimeMillis();
System.out.println("字符流拷贝文件消耗的时间是:"+(endtime-begintime)+"毫秒");//输出耗时
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 通过文件通道进行复制
* @param source 源文件
* @param target 目标文件
*/
private static void fileChannelCopy(File source, File target){
FileInputStream s = null;
FileOutputStream t = null;
FileChannel in = null;
FileChannel out = null;
try {
s = new FileInputStream(source);
t = new FileOutputStream(target);
in = s.getChannel();//得到对应的文件通道
out = t.getChannel();//得到对应的文件通道
long begintime = System.currentTimeMillis();
in.transferTo(0, in.size(), out);//连接两个通道,并且从in通道读取,然后写入out通道
long endtime = System.currentTimeMillis();
System.out.println("API拷贝文件消耗的时间是:" + (endtime - begintime) + "毫秒");//输出耗时
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
s.close();
t.close();
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
代码中,我分别拷贝了一个文本文件一个音频文件
最终在耗时方面
文本文档:
音频文件:
从耗时可以看出,在复制小文件的时候,几种方式的速度相差无几,但随着文件的增大,Java提供的方法要略快一些,字节缓冲流次之。
PS:在测试中,我们使用字符流复制MP3文件,但在实际应用中,字符流在使用的过程中会造成音频格式损坏。切记~