Java: la lecture des chaînes à partir d'un fichier à accès aléatoire avec tampon d'entrée

Je n'ai jamais eu de fermer les expériences avec Java IO API avant et je suis vraiment frustré maintenant. J'ai du mal à croire à quel étrange et complexe qu'il est et à quel point il pourrait être de faire une tâche simple.

Ma tâche: j'ai 2 positions (à partir de l'octet, la fin de l'octet), pos1 et pos2. J'ai besoin de lire entre les lignes de ces deux octets (y compris le départ, pour ne pas dire la fin d'un) et de les utiliser comme Chaîne UTF8 objets.

Par exemple, dans la plupart des langages de script, il serait très simple 1-2-3-liner comme ça (en Ruby, mais il sera essentiellement le même, Python, Perl, etc):

f = File.open("file.txt").seek(pos1)
while f.pos < pos2 {
  s = f.readline
  # do something with "s" here
}

Il en vient vite l'enfer avec Java IO Api 😉 En fait, je vois deux façons de lire les lignes (se terminant par \n) à partir régulière des fichiers locaux:

  • RandomAccessFile a getFilePointer() et seek(long pos), mais c'est readLine() lit non-UTF8 cordes (et même pas de tableaux d'octets), mais très étrange chaînes brisées de codage, et il n'a pas de mise en mémoire tampon (ce qui veut probablement dire que chaque read*() appel doit être traduit en un seul sous-tendent OS read() => assez lent).
  • BufferedReader a une grande readLine() méthode, et il peut même faire quelques recherche avec skip(long n), mais il n'a aucun moyen de déterminer le nombre d'octets qui a été déjà lu, de ne pas mentionner la position courante dans un fichier.

J'ai essayé d'utiliser quelque chose comme:

    FileInputStream fis = new FileInputStream(fileName);
    FileChannel fc = fis.getChannel();
    BufferedReader br = new BufferedReader(
            new InputStreamReader(
                    fis,
                    CHARSET_UTF8
            )
    );

... et puis, à l'aide de fc.position() pour obtenir fichier en cours de lecture de la position et de fc.position(newPosition) à définir, mais il ne semble pas fonctionner dans mon cas: ressemble, il retourne la position d'une mémoire tampon de pré-remplissage effectué par BufferedReader, ou quelque chose comme ça - ces compteurs semblent être arrondi à 16K incréments.

Dois-je vraiment mettre en œuvre tout cela par moi-même, c'est à dire un fichier readering interface:

  • me permettent d'obtenir/définir la position dans un fichier
  • tampon de lecture du fichier d'opérations
  • permettre la lecture de chaînes de caractères UTF8 (ou au moins permettre à des opérations comme "tout lire jusqu'à la prochaine \n")

Est-il un moyen plus rapide que la mise en œuvre de tout moi-même? Suis-je la supervision de quelque chose?

RandomAccessFile est conçu pour des données binaires. Bien qu'il permet de stocker et de récupérer des chaînes UTF-8 avec writeUTF/readUTF, comme vous l'avez trouvé, son readLine (et le DataInput de l'interface readLine en général) ne fonctionne pas sur UTF-8.
Êtes-vous autorisé à utiliser openJDK 7 (bêta) ou d'un 3ème parti lib comme Apache Commons IO?
merci de poster votre OpenJDK 7 et Apache Commons IO solutions de toute façon. Je suis curieux, et probablement d'autres personnes le sont aussi.
Verburg: je ne peux pas utiliser le JDK 7, mais un 3ème partie les bibliothèques sont les bienvenus. Merci de répondre, c'est intéressant 🙂
Bloom - j'ai donné la version de Java 7 un aller et c'est encore sacrément bavard et il a échoué lors de l'exécution avec les dernières openJDK construire :(. Le seul avantage est que vous pouvez utiliser plusieurs threads de lecture/écriture à partir du même fichier en parallèle. J'ai posté n'importe quoi. J'avoue ne pas avoir regardé les communes de fichier I/O choses encore, je suppose qu'ils avaient une API simple de JDK 1.5/1.6, je vais prendre un coup d'oeil à la prochaine

OriginalL'auteur GreyCat | 2010-11-29