之前有好幾次碰到檔案操作方面的問題,大都因為時間太趕而沒有好好花時間去仔細的研究研究,每次都是在百度或者部落格或者論壇裡面參照着大牛們寫的步驟照搬過來,之後再次碰到又忘記了,剛好今天比較清閑,于是就在網上找了找Java常用的file檔案操作方面的資料。之後加以一番整理,現分享給大家。
直接上源碼吧。
package com.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* file operate
* @author ruanpeng
* @time 2014-11-11上午9:14:29
*/
public class OperateFileDemo {
private DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS");
private Date start_time = null;//開始時間
private Date end_time = null;//結束時間
public static void main(String[] args) {
OperateFileDemo demo = new OperateFileDemo();
demo.operateFile1();
demo.operateFile2();
demo.operateFile3();
demo.fileCopy1();
demo.fileCopy2();
}
/**
* the first method of reading file
*/
public void operateFile1(){
start_time = new Date();
File f = new File("E:"+File.separator+"test.txt");//File.separator——windows is '\',unix is '/'
try {
//建立一個流對象
InputStream in = new FileInputStream(f);
//讀取資料,并将讀取的資料存儲到數組中
byte[] b = new byte[(int) f.length()];//資料存儲的數組
int len = 0;
int temp = 0;
while((temp = in.read()) != -1){//循環讀取資料,未到達流的末尾
b[len] = (byte) temp;//将有效資料存儲在數組中
len ++;
}
System.out.println(new String(b, 0, len, "GBK"));
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
end_time = new Date();
System.out.println("==============第一種方式——start_time:"+df.format(start_time));
System.out.println("==============第一種方式——end_time:"+df.format(end_time));
System.out.println("==============第一種方式總耗時:"+(end_time.getTime() - start_time.getTime())+"毫秒");
}
}
/**
* the second method of reading file
*/
public void operateFile2(){
start_time = new Date();
File f = new File("E:"+File.separator+"test.txt");
try {
InputStream in = new FileInputStream(f);
byte[] b = new byte[1024];
int len = 0;
while((len = in.read(b)) != -1){
System.out.println(new String(b, 0, len, "GBK"));
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
end_time = new Date();
System.out.println("==================第二種方式——start_time:"+df.format(start_time));
System.out.println("==================第二種方式——end_time:"+df.format(end_time));
System.out.println("==================第二種方式總耗時:"+(end_time.getTime() - start_time.getTime())+"毫秒");
}
}
/**
* the third method of reading file(檔案讀取(Memory mapping-記憶體映射方式))
* 這種方式的效率是最好的,速度也是最快的,因為程式直接操作的是記憶體
*/
public void operateFile3(){
start_time = new Date();
File f = new File("E:"+File.separator+"test.txt");
try {
FileInputStream in = new FileInputStream(f);
FileChannel chan = in.getChannel();//記憶體與磁盤檔案的通道,擷取通道,通過檔案通道讀寫檔案。
MappedByteBuffer buf = chan.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
byte[] b = new byte[(int) f.length()];
int len = 0;
while(buf.hasRemaining()){
b[len] = buf.get();
len++;
}
chan.close();
in.close();
System.out.println(new String(b,0,len,"GBK"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
end_time = new Date();
System.out.println("======================第三種方式——start_time:"+df.format(start_time));
System.out.println("======================第三種方式——end_time:"+df.format(end_time));
System.out.println("======================第三種方式總耗時:"+(end_time.getTime() - start_time.getTime())+"毫秒");
}
}
/**
* the first method of copying file
*/
public void fileCopy1(){
start_time = new Date();
File f = new File("E:"+File.separator+"test.txt");
try {
InputStream in = new FileInputStream(f);
OutputStream out = new FileOutputStream("F:"+File.separator+"test.txt");
int len = 0;
while((len = in.read()) != -1){
out.write(len);
}
out.close();
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
end_time = new Date();
System.out.println("======================第一種檔案複制方式——start_time:"+df.format(start_time));
System.out.println("======================第一種檔案複制方式——end_time:"+df.format(end_time));
System.out.println("======================第一種檔案複制方式總耗時:"+(end_time.getTime() - start_time.getTime())+"毫秒");
}
}
/**
* 使用記憶體映射實作檔案複制操作
*/
public void fileCopy2(){
start_time = new Date();
File f = new File("E:"+File.separator+"test.txt");
try {
FileInputStream in = new FileInputStream(f);
FileOutputStream out = new FileOutputStream("F:"+File.separator+"test2.txt");
FileChannel inChan = in.getChannel();
FileChannel outChan = out.getChannel();
//開辟緩沖區
ByteBuffer buf = ByteBuffer.allocate(1024);
while ((inChan.read(buf)) != -1){
//重設緩沖區
buf.flip();
//輸出緩沖區
outChan.write(buf);
//清空緩沖區
buf.clear();
}
inChan.close();
outChan.close();
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
end_time = new Date();
System.out.println("======================第二種檔案複制方式——start_time:"+df.format(start_time));
System.out.println("======================第二種檔案複制方式——end_time:"+df.format(end_time));
System.out.println("======================第二種檔案複制方式總耗時:"+(end_time.getTime() - start_time.getTime())+"毫秒");
}
}
}
說明:
前面三種方法是關于檔案的讀取操作,第一種和第二種是比較常見的普通方式,第三種則是采用記憶體映射的模式,這種模式是直接操作記憶體,效率是最快的,後面兩種是關于檔案的讀取和寫入操作。
這就是上面的程式運作的結果,上面說到第三種方式是直接面向記憶體的,效率是最快的,可是我們發現第三種的運作結果卻還沒有第二種方式快,具體的原因我還沒有進行深入探究,而且我的檔案容量也比較小,看不出什麼本質的效果,而且這個也僅僅是讀取操作,但最後的那個檔案複制操作效果就相當明顯了,不僅僅是讀取操作,同時還涉及到了檔案的寫操作,普通的複制方式需要105毫秒,而采用記憶體映射的方式僅僅隻需要1毫秒,效果立馬明曉了。
至于讀操作的效率問題有興趣的朋友可以去深入探究一番。
原文出處:http://www.open-open.com/lib/view/open1415448427183.html