La façon la plus rapide de mettre à lire un gros fichier

Lors d'une mémoire tampon de MAX_BUFFER_SIZE, et un fichier qui dépasse de loin, comment peut-on:

  1. Lire le fichier en blocs de MAX_BUFFER_SIZE?
  2. Faire aussi vite que possible

J'ai essayé d'utiliser NIO

    RandomAccessFile aFile = new RandomAccessFile(fileName, "r");
    FileChannel inChannel = aFile.getChannel();

    ByteBuffer buffer = ByteBuffer.allocate(CAPARICY);

    int bytesRead = inChannel.read(buffer);

    buffer.flip();

        while (buffer.hasRemaining()) {
            buffer.get();
        }

        buffer.clear();
        bytesRead = inChannel.read(buffer);

    aFile.close();

Et régulière IO

    InputStream in = new FileInputStream(fileName);

    long length = fileName.length();

    if (length > Integer.MAX_VALUE) {
        throw new IOException("File is too large!");
    }

    byte[] bytes = new byte[(int) length];

    int offset = 0;

    int numRead = 0;

    while (offset < bytes.length
            && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) {
        offset += numRead;
    }

    if (offset < bytes.length) {
        throw new IOException("Could not completely read file " + fileName);
    }

    in.close();

S'avère que régulière IO est environ 100 fois plus vite en faisant la même chose que NIO. Ai-je raté quelque chose? Est-ce prévu? Est-il un moyen plus rapide pour lire le fichier dans le tampon morceaux?

En fin de compte, je travaille avec un gros fichier, je n'ai pas de mémoire pour les lire tous à la fois. Au lieu de cela, j'aimerais lire de façon incrémentielle dans les blocs qui pourrait ensuite être utilisé pour le traitement.

NIO n'est pas nécessairement plus rapide, c'est juste différent. Si java.io est plus rapide pour vous, puis de les ignorer NIO.
NIO w/o ByteBuffers est inutile (ou au moins transferTo sur Linux, sur Windows, il est émulé, donc inutile)
NIO est (strictement) plus rapidement lorsqu'il est utilisé correctement, il n'exige pas de tampon de copie par rapport à la régulière les IO. Ce n'est pas très facile à utiliser pour les novices, si.
Je tiens seulement à souligner que vos deux impls sont en train de faire des choses différentes. Votre NIO code de l'exemple est la lecture des octets dans votre ByteBuffer, alors vous êtes la lecture de , un par un, à partir de la sauvegarde de byte[] dans le ByteBuffer et ne rien faire avec eux dans la boucle. Dans les IO du code de la lecture des octets dans le byte[] et à ne pas faire d'autres travaux. Votre NIO code est fait 2x le lit plus la des milliards d'appels à get() pour saisir des valeurs de chaque octet.

OriginalL'auteur JAM | 2012-01-28