Ben c'est tout simplement les paramètres d'entrée de la méthode read() du Reader :
- Le buffer dans lequel seront stocké les données
- La position initial dans le buffer
- Le nombre d'élément à lire
a++
Version imprimable
Ben c'est tout simplement les paramètres d'entrée de la méthode read() du Reader :
- Le buffer dans lequel seront stocké les données
- La position initial dans le buffer
- Le nombre d'élément à lire
a++
donc ça devrait donner un truc comme ça
mais ça ne marche pas, et puis je ne suis pas sure pour le nombre d'element...Code:
1
2 char[] cbuf = null; r.read(cbuf, 0, 3);
le off doit etre incrementé non?
Je ne comprend pas ce que tu veux dire par là... :koi:
Précises ton problème SVP !
a++
Non. Le buffer est un tableau de taille fixe (1024 par exemple). La méthode la plus courante est d'utiliser le buffer dans son intégralité. Donc :
Code:
1
2
3
4
5
6 char[] cbuf = new char[ 1024 ]; int taille = 0; while( ( taille = r.read( cbuf, 0, cbuf.length() ) ) > 0 ) { //traitement de cbuf, taille contient le nombre d'éléments remplis par read }
bein au fait je fais ça
et ça ne marche pas, le probleme est au niveau des read(cbuf,0,3)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Reader r = new MultiReader( new StringReader("<xml>"), new FileReader(monFichier), new StringReader("</xml>") ); try { char[] cbuf = null; r.read(cbuf, 0, 3); } finally { r.close(); }
tu m'avais dit cbuf c'est le buffer les données sont stockées donc j'ai créé un nouveau.
0 c'est la position initiale dans le buffer.
et 3 c'est le nombre d'elements a lire.
et ça ne marche pas, j'ai oublié un truc?
heu c'est pas sortie
Code:
1
2
3
4
5
6
7
8
9
10
11
12 Reader r = new MultiReader( new StringReader("<xml>"), new FileReader(monFichier), new StringReader("</xml>") ); try { char[] cbuf = null; r.read(cbuf, 0, 3); } finally { r.close(); }
Ben tu n'initialises pas le buffer... mais... Pourquoi tu lis toi même les données ???
Tu devrais simplement utiliser cela avec ton outils de parsing du XML ! :koi:
Là je suis perdu sur ce que tu veux faire précisément.
Je pense qu'il faudrait que tu reprennes tout à zéro en expliquant ton problème initial et ce dont tu as besoin, sans oublier le code... par ce que j'ai vraiment l'impression de tourner en rond là !!!
a++
ah je dois l'utiliser avec mon outil de parsing XML?:aie:
au fait je pensais qu'il me sortirais un nouveau fichier qui englobe les trois?
comment l'utiliser avec un parseur?
au fait moi j'ai un fuchier XML sans racine je veux la lui inserer pour pouvoir le traiter comme il se doit :)
excuse moi je suis un peu perdue la
je pense que demande trop mais STP a quel niveau passer le reader au parser?? dans cette ligne?fenetrefaits.document = sxb.build(new File(monFichier));Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 SAXBuilder sxb = new SAXBuilder(); try { Reader r = new MultiReader( new StringReader("<xml>"), new FileReader(monFichier), new StringReader("</xml>") ); fenetrefaits.document = sxb.build(new File(monFichier)); fenetrefaits.racine = fenetrefaits.document.getRootElement(); }
en sachant que monFichier c'est le fichier xml en entrée sans racine
merci beaucoup adiGuba. c'est genial ça marche enfin :D
L'idée du Multi Reader est super adiGuba, c'est très ingénieux :ccool:
Regarde la doc de l'API de ta classe SAXBuilder , http://www.jdom.org/docs/apidocs/org...a.io.Reader%29
Cherche bien avant de poser les questions, comme ça t'apprendra à être plus autonome :mrgreen:
merci pour le conseil hibour :).et encore merci a adiguba :)
Pour clore ce sujet et comme j'ai promis au début voici la classe optimisée (en l'occurrence) pour rajouter des données au début d'un fichier
CordialementCode:
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
53
54
55
56
57
58
59
60
61 import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; /** * * @author Bourada Hichem * @version 1.0 */ public final class FileAppender { //Tune this parameter to get the optimal speed private static final int BUFFER_SIZE = 1 << 16; // 64Ko private RandomAccessFile raf; public FileAppender(String name) throws FileNotFoundException { raf = new RandomAccessFile(name, "rw"); } public FileAppender writeFirst(byte[] data) throws IOException { byte[] buf = new byte[BUFFER_SIZE]; long length = raf.length(); long readPos = length; int nbread; while (readPos > 0) { if (readPos >= BUFFER_SIZE) { nbread = BUFFER_SIZE; readPos -= BUFFER_SIZE; } else { nbread = (int) readPos; readPos = 0; } raf.seek(readPos); nbread = raf.read(buf, 0, nbread); raf.seek(readPos + data.length); raf.write(buf, 0, nbread); } raf.seek(0L); raf.write(data); return this; } public FileAppender writeFirst(String data) throws IOException { raf.writeChars(data); return this; } public void close() throws IOException { raf.close(); } public static void main(String[] args) throws Exception { FileAppender appender = new FileAppender("test.properties"); appender.writeFirst("test.zzzzz=TEST3\n".getBytes()); appender.writeFirst("test.yyyyy=TEST2\n".getBytes()); appender.writeFirst("test.xxxxx=TEST1\n".getBytes()); appender.close(); } }
Oui, j'ai quelques chiffres qui vont te donner du réconfort :mrgreen:
Je ne veux surtout pas troller ou même critiquer ton code. Mais j'ai fais quelques tests entre ton code et la technique de création d'un nouveau fichier. La taille du buffer est évidemment un point très sensible. Voici les résultats pour un fichier de 126 Mo, Java 6, Système AIX 5.3 et 5 tests successifs pour chacune des méthodes :
buffer 512 octets :
méthode déplacement : environ 3.7 secondes
méthode nouveau fichier : environ 1.1 secondes
buffer 1 Ko :
méthode déplacement : environ 2 secondes
méthode nouveau fichier : environ 1.1 secondes
buffer 32 Ko :
méthode déplacement : environ 1.5 secondes
méthode nouveau fichier : environ 1.1 secondes
buffer 64 Ko :
méthode déplacement : environ 1.5 secondes
méthode nouveau fichier : environ 1.1 secondes
buffer 128 Ko :
méthode déplacement : environ 1.6 secondes
méthode nouveau fichier : environ 1.3 secondes
buffer 256 Ko :
méthode déplacement : environ 7.1 secondes (refait 2 fois, il n'y a pas d'erreur...)
méthode nouveau fichier : environ 1.1 secondes
buffer 512 Ko :
méthode déplacement : environ 4.3 secondes (refait 2 fois, pas d'errreur non plus...)
méthode nouveau fichier : environ 1.1 secondes
buffer 1 Mo :
méthode déplacement : environ 2.3 secondes
méthode nouveau fichier : environ 1.2 secondes
C'était juste pour info.
Et le code est potentiellement buggé, à cause de ceci :
:arrow: C'est bien de récupérer le retour du read() dans nbread pour le passer au write(), car sinon on pourrait écrire des données invalides...Code:
1
2
3 nbread = read(buf, 0, nbread); // ... raf.write(buf, 0, nbread);
Mais le problème c'est que la valeur de retour du read() ne correspond pas forcément au paramètre nbread passé. En fait cela lira au plus "nbread" octets...
Le problème n'est pas facilement reproductible, car dans la plupart des cas tous les octets seront bien lu. Mais en cas de surcharge du système, il est possible de recevoir moins de données afin d'éviter un blocage I/O. En clair plutôt que de bloquer le process on lui renvoi le peu de données lu, afin qu'il puisse les traiter en attendant la suite...
Le problème c'est que dans ce cas là on "oublie" de copier une partie des données... :(
Il faut remplacer cela par un readFully() qui attendra que la quantité de données demandées soit bien lu :
Code:raf.readFully(buf, 0, nbread);
a++
Je savais qu'il y avait un potentiel infime d'erreur :ccool:
Si on regarde dans la classe RadomAccessFile on voit que readBytes est une méthode native (peut être implémenté en C à l'aide de fread())..
La méthode readFully() fait appel a read() -> le cas d'erreur est très rare que je l'ai zappé, On peut néanmoins lancer une exeption si ce cas se produit en comparant nbread retourné et celui qui est lu..
Merci pour la remarque.
a++
bein au fait adiGuba j'ai un autre probleme, comme les fichiers xml sont trés volumineux (500 M) donc impossible d'utilisé XMLBuilder, je me suis rabbatue sur le XMLReader maisdans son parse impossible de mettre un reader en entrée...:'(
Ben déjà il faut savoir ce qu'il attend comme source de données (d'où elle sort ta classe XMLReader déjà), et tu adaptes le code.
Cette notion de flux est utilisé partout en Java, donc tu peux facilement reproduire le cas...
[edit] hibour : c'était surtout pour signaler le comportement du read() qui n'est pas garantie, et qui peut parfois surprendre ;)
a++