Bien le bonjour,
J'ai besoin de lire des lignes dans un fichier, et ce pour des fichiers de toute taille.
Jusque là j'utilisais un bon vieux BufferedReader, les performances étant au rendez-vous.
Pour le fun, je me suis mis dans la tête de faire un tour du côté du package java.nio et ses FileChannel, ByteBuffer.
Pour simplifier mon code, j'ai pondu une classe permettant la lecture de lignes :
Ce qui est étrange, c'est que je perds énormément en performances. Par exemple, sur un fichier texte d'environ 700 Ko, un BufferedReader ( et sa méthode readLine() ) demande à peine 1 seconde pour lire 10 fois tout le fichier, alors qu'avec java.nio je passe à plus de 4 secondes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 package com.grosbidule.gcon4j.util.nio; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class FastFileReader { private FileChannel fc; private ByteBuffer buffer; private StringBuilder line; private char c; public FastFileReader(File f) throws FileNotFoundException, IOException { buffer = ByteBuffer.allocate((int)f.length()); fc = new FileInputStream(f).getChannel(); fc.read(buffer); buffer.rewind(); } public void close() throws IOException { fc.close(); } // lecture d'une ligne. Il me faut le même comportement // que la méthode readline() d'un BuferedReader. public String readLine() { if (false == buffer.hasRemaining()) { return null; } // prend la moitiée du temps line = new StringBuilder(); // la boucle while prend l'autre moitiée du temps while (buffer.hasRemaining()) { c = (char)buffer.get(); if ((c == '\n') || (c == '\r')) { break; } line.append(c); } return line.toString(); } }
Le fichier de test contient des lignes allant de 0 à plus de 10 000 caractères (pour le fun ^^).
J'ai regardé le tutoriel présent : sur gfx.developpez.com, mais visiblement il y a quelque chose que je dois comprendre de travers, mais quoi ?
Peut être un problème ailleurs que dans java.nio ..., j'avais pensé à l'affectation de mon StringBuilder dans la méthode readLine, mais elle ne prend "que" la moitié du temps (mais bon ça semble quand même à corriger, et là je bloque aussi). En changeant la taille de mon StringBuilder, je ne fais que perdre en performance.
En vous remerciant pour vos lumières.
Partager