使用Java查找文件中有多少非空行的最快方法是什么?
最简单的方法是使用BufferedReader,并检查哪些行为空.但是,这是一种相对较慢的方法,因为它需要为文件中的每一行创建一个String对象.更快的方法是使用read()将文件读入数组,然后遍历数组以计算换行符.
这是两个选项的代码; 第二个占用了我机器上大约50%的时间.
public static void timeBufferedReader () throws IOException { long bef = System.currentTimeMillis (); // The reader buffer size is the same as the array size I use in the other function BufferedReader reader = new BufferedReader(new FileReader("test.txt"), 1024 * 10); int counter = 0; while (reader.ready()) { if (reader.readLine().length() > 0) counter++; } long after = System.currentTimeMillis() - bef; System.out.println("Time: " + after + " Result: " + counter); } public static void timeFileReader () throws IOException { long bef = System.currentTimeMillis(); FileReader reader = new FileReader("test.txt"); char[] buf = new char[1024 * 10]; boolean emptyLine = true; int counter = 0; while (reader.ready()) { int len = reader.read(buf,0,buf.length); for (int i = 0; i < len; i++) { if (buf[i] == '\r' || buf[i] == '\n') { if (!emptyLine) { counter += 1; emptyLine = true; } } else emptyLine = false; } } long after = System.currentTimeMillis() - bef; System.out.println("Time: " + after + " Result: " + counter); }
我在NIO推荐的Limbic系统上.我已经为Daphna的测试代码添加了一个NIO方法,并且基于他的两种方法对它进行了标记:
public static void timeNioReader () throws IOException { long bef = System.currentTimeMillis(); File file = new File("/Users/stu/test.txt"); FileChannel fc = (new FileInputStream(file)).getChannel(); MappedByteBuffer buf = fc.map(MapMode.READ_ONLY, 0, file.length()); boolean emptyLine = true; int counter = 0; while (buf.hasRemaining()) { byte element = buf.get(); if (element == '\r' || element == '\n') { if (!emptyLine) { counter += 1; emptyLine = true; } } else emptyLine = false; } long after = System.currentTimeMillis() - bef; System.out.println("timeNioReader Time: " + after + " Result: " + counter); }
以下是89MB文件的预热结果:
timeBufferedReader Time: 947 Result: 747656 timeFileReader Time: 670 Result: 747656 timeNioReader Time: 251 Result: 747656
NIO比FileReader快2.5倍,比BufferedReader快4倍!
使用6.4MB文件,结果甚至更好,尽管预热时间更长.
//jvm start, warming up timeBufferedReader Time: 121 Result: 53404 timeFileReader Time: 65 Result: 53404 timeNioReader Time: 40 Result: 53404 //still warming up timeBufferedReader Time: 107 Result: 53404 timeFileReader Time: 60 Result: 53404 timeNioReader Time: 20 Result: 53404 //ripping along timeBufferedReader Time: 79 Result: 53404 timeFileReader Time: 56 Result: 53404 timeNioReader Time: 16 Result: 53404
按照你的意愿做到.