複製文件的比較
Io是web端不可不談的一個重點,而複製則是一個典型的運用,從複製中可以瞭解各中io的運用及效率
原生IO
@Test
public void executeInputStream() {
String srcFile = "E:/電子書/白帽子講Web安全.pdf";
String tarFile = "E:/book.pdf";
long start = System.currentTimeMillis();
FileInputStream fis = null;
FileOutputStream fos = null;
File f = new File(srcFile);
System.out.println("File size="+f.length());
try {
fis = new FileInputStream(f);
fos = new FileOutputStream(tarFile);
int len = 0;
byte[] b = new byte[1024];
while ((len = fis.read(b)) != -1) {
fos.write(b);
fos.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("用時:" + (end - start) + "毫秒");
}
console輸出內容 這是運行過一次的第一次2600+ms 第二次的就變成了這個了,究其原因是是已有一份緩存內核緩存,導致第二次比第一次少很多,具體詳見這篇文章
文本文檔是這樣的和NIO相差不太多,圖像音頻視頻的話是比NIO慢許多的
BufferedInputStream Buff加成
@Test
public void runBufferedPutStream() {
String srcFile = "E:/電子書/白帽子講Web安全.pdf";
String tarFile = "E:/book.pdf";
long start = System.currentTimeMillis();
int len = 0;
byte[] b = new byte[1024];
BufferedOutputStream fos = null;
BufferedInputStream fis = null;
try {
fos = new BufferedOutputStream(new FileOutputStream(new File(tarFile)));
fis = new BufferedInputStream(new FileInputStream(new File(srcFile)));
while ((len = fis.read(b)) != -1) {
fos.write(b);
fos.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("用時:" + (end - start) + "毫秒");
}
BufferedOutputStream與BufferedInputStream 我們都知道加了一層buff更吊了,加了一個緩存層效率確實高了一些
console打印
和原生IO相比可以看到確實提高一些,文件是相同的我這裏沒有打印,
這個多運行幾次得到的時間是相同的,也佐證了這個已經加了buffer層,第一次第二次不會有區別了。
BufferedRead Writer
@Test
public void runBufferedStreamReaderAndWriter() throws IOException {
String srcFile = "E:/電子書/白帽子講Web安全.pdf";
String tarFile = "E:/book.pdf";
long start = System.currentTimeMillis();
BufferedReader br = new BufferedReader(new FileReader(new File(srcFile)));
BufferedWriter fr = new BufferedWriter(new FileWriter(new File(tarFile)));
int len = 0;
char[] ch = new char[1024];
while ((len = br.read(ch)) != -1) {
fr.write(ch);
}
long end = System.currentTimeMillis();
System.out.println("用時:" + (end - start) + "毫秒");
br.close();
fr.close();
}
pdf類型的原因吧
FileChannel
@Test
public void runChannelMapped() throws IOException {
String srcFile = "E:/電子書/白帽子講Web安全.pdf";
String tarFile = "E:/book.pdf";
long start = System.currentTimeMillis();
// 獲取通道
// 讀模式
FileChannel inChannel = FileChannel.open(Paths.get(srcFile), StandardOpenOption.READ);
// 讀寫模式
FileChannel outChannel = FileChannel.open(Paths.get(tarFile), StandardOpenOption.WRITE, StandardOpenOption.READ,
StandardOpenOption.CREATE);
// 內存映射文件
MappedByteBuffer inBuf = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
// 對緩衝區的數據進行讀寫操作
byte[] by = new byte[inBuf.limit()];
inBuf.get(by);
outBuf.put(by);
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("耗費時間:" + (end - start));
}
channel 加mappedBytebuffer 內存映射得到的效果
這之後還有一個直接轉換channel直接對接的方法,transferForm 效率最高
// 通道之間的數據傳輸,直接緩衝區
@Test
public void runTransFerChannel() throws IOException {
String srcFile = "E:/電子書/白帽子講Web安全.pdf";
String tarFile = "E:/book.pdf";
FileChannel inChannel = null;
FileChannel outChannel = null;
long start = System.currentTimeMillis();
try {
// 讀模式
inChannel = FileChannel.open(Paths.get(srcFile), StandardOpenOption.READ);
// 讀寫模式
outChannel = FileChannel.open(Paths.get(tarFile), StandardOpenOption.WRITE, StandardOpenOption.READ,
StandardOpenOption.CREATE);
// inChannel.transferTo(0, inChannel.size(), outChannel);
outChannel.transferFrom(inChannel, 0, inChannel.size());
} catch (Exception e) {
e.printStackTrace();
} finally {
inChannel.close();
outChannel.close();
}
long end = System.currentTimeMillis();
System.out.println("execute time==" + (end - start));
}
效率達到了最高