一:緩衝輸入輸出流(InputStream、OutputStream)
[java] view plain copy
<span style="font-size:14px;"> /*
*緩衝輸入輸出流方式複製文件
*/
public static boolean copyFile(String srcFileName,String destFileName,boolean overlay){
File srcFile = new File(srcFileName); //根據一個路徑得到File對象
//判斷源文件是否存在
if(!srcFile.exists()){
try{
throw new Exception("源文件:"+srcFileName+"不存在!");
}catch(Exception e){
e.printStackTrace();//將異常內容存到日誌文件中
}
return false;
}else if(!srcFile.isFile()){//判斷是不是一個文件
try {
throw new Exception("複製文件失敗,源文件:"+srcFileName+"不是一個文件!");
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
//判斷目標文件是否存在
File destFile = new File(destFileName);//目標文件對象destFile
if(destFile.exists()){
//如果目標文件存在並允許覆蓋
if(overlay){
//刪除已經存在的目標文件
new File(destFileName).delete();
}
}else{
//如果目標文件所在目錄不存在,則創建 目錄
if(!destFile.getParentFile().exists()){
//目標文件所在目錄不存在
//mkdirs():創建此抽象路徑名指定的目錄,包括所有必需但不存在的父目錄
if(!destFile.getParentFile().mkdirs()){
//複製文件失敗:創建目標文件所在目錄失敗
return false;
}
}
}
//複製文件
int byteread = 0;//讀取的字節數
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(srcFile);
out = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
/*
* 方法說明:
* ①:將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
* write(byte[] b, int off, int len)
* b - 數據
* off - 數據中的起始偏移量。
* len - 要寫入的字節數。
* ②:in.read(buffer))!=-1,是從流buffer中讀取一個字節,當流結束的時候read返回-1
*/
while((byteread = in.read(buffer))!=-1){
out.write(buffer, 0, byteread);
}
return true;
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
}finally{
try {
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}</span>
二:文件通道(FileChannel)
[java] view plain copy
<span style="font-size:14px;"> /*
* 使用文件通道的方式複製文件
*/
public static void fileChannelCopy(String srcDirName,String destDirName){
FileInputStream fi = null;
FileOutputStream fo = null;
FileChannel in = null;
FileChannel out = null;
try {
fi = new FileInputStream(new File(srcDirName));
fo = new FileOutputStream( new File(destDirName));
in = fi.getChannel();//得到對應的文件通道
out = fo.getChannel();//得到對應的文件通道
/*
* public abstract long transferTo(long position, long count,
WritableByteChannel target)throws IOException;
* position - 文件中的位置,從此位置開始傳輸;必須爲非負數
* count - 要傳輸的最大字節數;必須爲非負數
* target - 目標通道
* 返回:
實際已傳輸的字節數,可能爲零
*/
in.transferTo(0, in.size(), out);//連接兩個通道,並且從in通道讀取,然後寫入out通道中
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fi.close();
in.close();
fo.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}</span>
測試上面的兩個方法:
[java] view plain copy
<span style="font-size:14px;">public class copyFile{
public static void main(String[] args) {
String srcDirName = "E:/360cse_official.exe";//待複製的文件名
String destDirName ="E:/360cse_official_test.exe";//目標文件名
long start;
long end;
start = System.currentTimeMillis();//返回系統的當前時間
copyFile.copyFile(srcDirName,destDirName,true);
end = System.currentTimeMillis();
System.out.println("緩衝輸入輸出流方式複製文件,用時:"+(end-start)+"ms");
start = System.currentTimeMillis();
copyFile.fileChannelCopy(srcDirName,destDirName);
end = System.currentTimeMillis();
System.out.println("使用文件通道的方式複製文件,用時:"+(end-start)+"ms");
}</span>
測試文件:
運行結果:
緩衝輸入輸出流方式複製文件,用時:499ms
使用文件通道的方式複製文件,用時:57ms
總結:
通過對上面兩個方法測試,我們可以知道使用文件通道的方式複製文件,明顯比輸出流複製文件效率要高。
學到的知識點:
①:返回系統的當前時間:start = System.currentTimeMillis();
②:write(byte[] b, int off, int len) 方法
將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流
b - 數據
off - 數據中的起始偏移量。
len - 要寫入的字節數。
③:in.read(buffer))!=-1,是從流buffer中讀取一個字節,當流結束的時候read返回-1
④:in.transferTo(0, in.size(), out);//連接兩個通道,並且從in通道讀取,然後寫入out通道中
public abstract long transferTo(long position, long count,
WritableByteChannel target)throws IOException;
position - 文件中的位置,從此位置開始傳輸;必須爲非負數
count - 要傳輸的最大字節數;必須爲非負數
target - 目標通道
返回:
實際已傳輸的字節數,可能爲零