复制文件的比较
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));
}
效率达到了最高