Java La forma más rápida de leer archivos de texto con 2 millones de líneas


Actualmente estoy usando scanner/filereader y usando while hasnextline. Creo que este método no es muy eficiente. ¿Hay algún otro método para leer el archivo con la funcionalidad similar de este?

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();
        }
    }
 24
Author: BeyondProgrammer, 2013-10-21

6 answers

Usted encontrará que BufferedReader.readLine() es tan rápido como necesitas: puedes leer millones de líneas por segundo con él. Es más probable que la división y el manejo de la cadena esté causando cualquier problema de rendimiento que esté encontrando.

 26
Author: user207421,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-07 19:55:35

Scanner no puede ser tan rápido como BufferedReader, ya que utiliza expresiones regulares para leer archivos de texto, lo que lo hace más lento en comparación con BufferedReader. Usando BufferedReader puede leer un bloque de un archivo de texto.

BufferedReader bf = new BufferedReader(new FileReader("FileName"));

Puede usar a continuación readLine() para leer desde bf.

Espero que sirva a tu propósito.

 4
Author: shamsAAzad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-12 03:46:56

Puedes usar FileChannel y ByteBuffer desde JAVA NIO. El tamaño del ByteBuffer es la parte más crítica en la lectura de datos más rápido de lo que he observado. El siguiente código leerá el contenido del archivo.

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();
    }

Puede buscar '\n' para una nueva línea aquí. Gracias.


Incluso usted puede dispersar y getter manera de leer archivos más rápido, es decir,

fileChannel.get(buffers);

Donde

      ByteBuffer b1 = ByteBuffer.allocate(B1);
      ByteBuffer b2 = ByteBuffer.allocate(B2);
      ByteBuffer b3 = ByteBuffer.allocate(B3);

      ByteBuffer[] buffers = {b1, b2, b3};

Esto evita que el proceso de usuario realice varias llamadas al sistema (lo que puede ser costoso) y permite que el kernel optimice el manejo de los datos porque tiene información sobre la transferencia total, si hay varias CPU disponibles, incluso puede ser posible llenar y drenar varios buffers simultáneamente.

De este libro.

 2
Author: Trying,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-21 05:10:53

Debe investigar qué parte del programa está tomando tiempo.

Según la respuesta de EJP, debe usar BufferedReader.

Si realmente el procesamiento de cadenas está tomando tiempo, entonces debería considerar usar subprocesos, un subproceso leerá desde las líneas de archivo y colas. Otra cadena procesador de hilos de cola, líneas de proceso y de ellos. Necesitará investigar cuántos subprocesos usar, el número de subprocesos que debe usar en la aplicación debe estar relacionado con el número de núcleos en la CPU, en de esa manera se utilizará la CPU completa.

 0
Author: nullptr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-21 05:07:08

Use BufferedReader para acceder a archivos de alto rendimiento. Pero el tamaño predeterminado del búfer de 8192 bytes es a menudo demasiado pequeño. Para archivos de gran tamaño puede aumentar el tamaño del búfer por órdenes de magnitudes para aumentar el rendimiento de lectura de archivos. Por ejemplo:

BufferedReader br = new BufferedReader("file.dat", 1000 * 8192);
while ((thisLine = br.readLine()) != null) {
    System.out.println(thisLine);
}  
 0
Author: mac7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 14:46:27

Si desea leer todas las líneas juntas, debería echar un vistazo a la API de archivos de java 7. Es muy fácil de usar.

Pero un mejor enfoque sería procesar este archivo en un lote. Tenga un lector que lea trozos de líneas del archivo y un escritor que haga el procesamiento requerido o persista los datos. Tener abatch asegurará que funcionará incluso si las líneas aumentan a mil millones en el futuro. También puede tener un lote que utiliza un multihilo para aumentar la totalidad rendimiento del lote. Le recomendaría que eche un vistazo a Spring batch.

 -1
Author: Pratik Shelar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-21 05:11:58