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++
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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à...
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 }
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Que la force de la puissance soit avec le courage de ta sagesse.
bein au fait je fais ça
et ça ne marche pas, le probleme est au niveau des read(cbuf,0,3)
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 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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 !
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?
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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
L'idée du Multi Reader est super adiGuba, c'est très ingénieux
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
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
Cordialement
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
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
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.
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Que la force de la puissance soit avec le courage de ta sagesse.
Et le code est potentiellement buggé, à cause de ceci :
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part raf.readFully(buf, 0, nbread);
a++
Je savais qu'il y avait un potentiel infime d'erreur
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++
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager