对于读文件NIO与IO谁快?
如果加一些复杂环境,然后再让他们去读文件呢?
为了得到这个答案,我做了两组实验,首先是直接单线程去读一个很大的文件,分别通过NIO和IO去读:
/**
* nio 读
*
* @param fileName
*/
public static void readFileWithNIO(String fileName) {
try {
long now = new Date().getTime();
FileInputStream fs = new FileInputStream(fileName);
FileChannel fc = fs.getChannel();
ByteBuffer bb = ByteBuffer.allocate(1024);
while (true) {
bb.clear();
int count = fc.read(bb);
if (count == -1)
break;
// System.out.println(new String(bb.array()));
}
fc.close();
fs.close();
System.out.println("nio read time:" + (new Date().getTime() - now)
+ "ms");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void readFileWithIO(String fileName) {
try {
long now = new Date().getTime();
FileInputStream fs = new FileInputStream(fileName);
byte bb[] = new byte[1024];
while (fs.read(bb) != -1) {
// System.out.println(new String(bb));
}
fs.close();
System.out.println("io read time:" + (new Date().getTime() - now)
+ "ms");
} catch (Exception e) {
e.printStackTrace();
}
}
结果相信测试过的人都知道,IO的速率一般来讲都是NIO的3倍多,说明单线程读文件,IO比NIO快。
对于这个结论并不奇怪,因为NIO的特性明确标明是 非阻塞。单线程读文件,很难体现这个非阻塞的特点,非阻塞的言外之意是可以干别的事情。于是,我做了如下实验,我用多线程去读文件,也是分别用IO和NIO,这个时候的测试结果发现NIO和IO已经非常接近了,但是还是IO快。于是,我有增加了额外的线程在读文件的同时去干一些其他的事情,这个时候,我终于发现NIO比IO快了,代码如下:
public static void readFileWithNIOMultThread(String fileName) {
try {
long now = new Date().getTime();
FileInputStream fs = new FileInputStream(fileName);
final FileChannel fc = fs.getChannel();
class TestThread implements Runnable {
public void run() {
ByteBuffer bb = ByteBuffer.allocate(102400);
try {
while (true) {
bb.clear();
int count = fc.read(bb);
if (count == -1)
break;
// System.out.println(new String(bb.array()));
// Thread.sleep((long)(Math.random() * 1000));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ArrayList<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
Thread tmp = new Thread(new TestThread());
list.add(tmp);
tmp.start();
}
for (int i = 0; i < 10; i++) {
Thread tmp = new Thread(new Runnable() {
public void run() {
try {
for(int i=0;i<1000;i++){
System.out.println(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
list.add(tmp);
tmp.start();
}
for (Thread t : list) {
t.join();
}
fc.close();
fs.close();
System.out.println("nio read time:" + (new Date().getTime() - now)
+ "ms");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void readFileWithIOMultThreads(String fileName) {
long now = new Date().getTime();
try {
final FileInputStream fs = new FileInputStream(fileName);
class TestThread implements Runnable {
public void run() {
byte bb[] = new byte[102400];
try {
while (fs.read(bb) != -1) {
// System.out.println(new String(bb));
// Thread.sleep((long)(Math.random() * 1000));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ArrayList<Thread> list = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
Thread tmp = new Thread(new TestThread());
list.add(tmp);
tmp.start();
}
for (int i = 0; i < 10; i++) {
Thread tmp = new Thread(new Runnable() {
public void run() {
try {
for(int i=0;i<1000;i++){
System.out.println(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
list.add(tmp);
tmp.start();
}
for (Thread t : list) {
t.join();
}
fs.close();
System.out.println("io read time:" + (new Date().getTime() - now)
+ "ms");
} catch (Exception e) {
e.printStackTrace();
}
}