Java用于读取200万行文本文件的最快方式
目前我正在使用扫描仪/文件读取器并使用whilenextline。 我认为这种方法效率不高。 有没有其他方法来读取具有类似function的文件?
public void Read(String file) { Scanner sc = null; try { sc = new Scanner(new FileReader(file)); while (sc.hasNextLine()) { String text = sc.nextLine(); String[] file_Array = text.split(" ", 3); if (file_Array[0].equalsIgnoreCase("case")) { //do something } else if (file_Array[0].equalsIgnoreCase("object")) { //do something } else if (file_Array[0].equalsIgnoreCase("classes")) { //do something } else if (file_Array[0].equalsIgnoreCase("function")) { //do something } else if (file_Array[0].equalsIgnoreCase("ignore")) { //do something } else if (file_Array[0].equalsIgnoreCase("display")) { //do something } } } catch (FileNotFoundException e) { System.out.println("Input file " + file + " not found"); System.exit(1); } finally { sc.close(); } }
您会发现BufferedReader.readLine()
的速度与您的需求一样快:您可以每秒读取数百万行。 您的字符串拆分和处理更可能导致您遇到的任何性能问题。
Scanner
不能像BufferedReader
一样快,因为它使用正则表达式来读取文本文件,这使得它比BufferedReader
慢。 通过使用BufferedReader
您可以从文本文件中读取块。
BufferedReader bf = new BufferedReader(new FileReader("FileName"));
你可以接下来使用readLine()来读取bf。
希望它符合您的目的。
你可以使用JAVA NIO的FileChannel和ByteBuffer 。 ByteBuffer大小是我观察到的更快读取数据的关键部分。 下面的代码将读取文件的内容。
static public void main( String args[] ) throws Exception { FileInputStream fileInputStream = new FileInputStream( new File("sample4.txt")); FileChannel fileChannel = fileInputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); fileChannel.read(byteBuffer); byteBuffer.flip(); int limit = byteBuffer.limit(); while(limit>0) { System.out.print((char)byteBuffer.get()); limit--; } fileChannel.close(); }
您可以在此处检查新行的’\ n’。 谢谢。
即使你可以分散和获取更快地读取文件的方式,即
fileChannel.get(buffers);
哪里
ByteBuffer b1 = ByteBuffer.allocate(B1); ByteBuffer b2 = ByteBuffer.allocate(B2); ByteBuffer b3 = ByteBuffer.allocate(B3); ByteBuffer[] buffers = {b1, b2, b3};
这样可以避免用户进程进行多次系统调用(这可能很昂贵),并允许内核优化数据处理,因为它有关于总传输的信息,如果有多个CPU可用,甚至可以填充和排空多个缓冲区同时。
从这本书。
您必须调查程序的哪个部分需要时间。
根据EJP的答案,您应该使用BufferedReader。
如果真正的字符串处理花费时间,那么你应该考虑使用线程,一个线程将从文件和队列行读取。 其他字符串处理器线程将使队列出列并处理它们。 您需要调查要使用的线程数,应该在应用程序中使用的线程数必须与CPU中的核心数相关,这样就会使用完整的CPU。
使用BufferedReader进行高性能文件访问。 但是默认缓冲区大小为8192字节通常太小。 对于大型文件,您可以按数量级增加缓冲区大小 ,以提高文件读取性能。 例如:
BufferedReader br = new BufferedReader("file.dat", 1000 * 8192); while ((thisLine = br.readLine()) != null) { System.out.println(thisLine); }
如果您希望一起阅读所有行,那么您应该看一下java 7的Files API。它非常简单易用。
但更好的方法是批量处理此文件。 让读者从文件中读取大量的行,并使用编写器执行所需的处理或持久保存数据。 即使生产线在未来增加到十亿,它也会确保它能够正常运转。 您还可以使用multithreading批处理来提高批处理的整体性能。 我建议你看一下春季批次。