[Java] Tracer une courbe en fonction des valeurs dans un fichier

Signaler
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013
-
 Utilisateur anonyme -
Bonjour,

je suis entrain de développer un logiciel en Java sous Eclipse.

J'ai des fichiers de ce type avec un nombre de ligne qui varie d'un fichier à l'autre:
"15/02/2012",16,17.0,3.6
"18/02/2012",5,7.4,2.5
"18/02/2012",12,7.6,2.5
...


Ces fichier ont un nombre de ligne de l'ordre de 1500 lignes avec 19 termes par ligne.

Je veux pouvoir séparer mes données afin de pouvoir les afficher dans un graphique par type.
J'ai déjà fais un code qui marche mais il faut 30 minutes (en ayant chronométré) pour afficher 2 graphiques. Je voudrais pouvoir diminuer considérablement ce temps mais je ne vois pas vraiment comment.

Étant débutant, je pense qu'il y a beaucoup de choses que je ne fais pas correctement et du coup je perd beaucoup de temps.

Par exemple, je lis le fichier ligne par ligne, puis je les regroupe et enfin je les redécoupe.
J'aimerai faire quelque chose de plus simple mais je n'arrive pas. Il y a sûrement d'autre erreur comme cela.


Code pour séparer les différents termes dans un tableau :
public String[] lire (String path) 
{
BufferedReader lect ;
String tmp = "";
String bufferComplet[] = new String[25];

try
{
lect = new BufferedReader(new FileReader(path)) ;

while (lect.ready()==true) 
{
tmp += lect.readLine() ; 
tmp += ",";
count ++;
}
bufferComplet = separateur(tmp, count);
}
catch (NullPointerException a)
{
System.out.println("Erreur : pointeur null");
}
catch (IOException a) 
{
System.out.println("Problème d'IO");
}
return bufferComplet;
}// fin du fichier lecture

public String[] separateur (String buffer, int nombreLignes){    

java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(buffer, ",\r\n");

int nombreColonnes = 19;
String buffer0[] = new String[nombreLignes*nombreColonnes+1];
String token;				
int test = 0;

while ( tokenizer.hasMoreTokens() ) {
token = tokenizer.nextToken();
    
buffer0[test]= token;
test++;		
}
return buffer0;
}



Code pour afficher les graphes :
// Créer et afficher graphique XY
XYSeries seriesDroit = new XYSeries("Débit droit");
XYSeries seriesGauche = new XYSeries("Débit gauche");
AnalyseView analyse = new AnalyseView();

for (int i=2 ; i<20000 ;i+=19) //20000
{
double point = Double.parseDouble(analyse.lire("docTest/test1.mid")[i]);	
seriesDroit.add(i, point);
}
for (int i=3 ; i<20000 ;i+=19) //20000
{
double point2 = Double.parseDouble(analyse.lire("docTest/test1.mid")[i]);
seriesGauche.add(i, point2);
}
               
XYDataset xyDataset = new XYSeriesCollection(seriesDroit);
XYDataset xyDatasetGauche = new XYSeriesCollection(seriesGauche);
  
JFreeChart chart = ChartFactory.createXYLineChart
("XYLine Chart using JFreeChart", "Différentes mesures", "Débit (l/min)",
xyDataset, PlotOrientation.VERTICAL, true, true, false);
  
JFreeChart chartGauche = ChartFactory.createXYLineChart
("XYLine Chart using JFreeChart", "Différentes mesures", "Débit (l/min)",
xyDatasetGauche, PlotOrientation.VERTICAL, true, true, false);
  
ChartFrame frame1=new ChartFrame("XYLine Chart",chart);
ChartFrame frameGauche=new ChartFrame("XYLine Chart",chartGauche);
  	
frame1.setSize(700,500);
frameGauche.setSize(700,500);
  
frameGauche.setLocation(700,0);
  
frame1.setVisible(true);
frameGauche.setVisible(true);



Si vous avez des idées d'amélioration de suis preneur.

Merci.
Bonne journée.

13 réponses

Messages postés
6413
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
17 mai 2018
286
Salut,

Pour lire ton fichier :

/**
 * fonction qui lit le contenu d'un fichier
 * @param nomFichier 
 * 	nom du fichier en entree
 * @return la liste des lignes
 */
public String lireFichier(String fichier){
StringBuilder sb = new StringBuilder();
try{
BufferedReader buff = new BufferedReader(new FileReader(fichier));
try {
String line;
while ((line = buff.readLine()) != null) {
sb.append(line).append(FIN_LIGNE);
}
} 
finally {
buff.close();
}
} 
catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}


Tu récupères un String, pour récupérer un tableau de lignes :
String[] lignes = lignes.split("\n");


et ensuite, pour chaque ligne :

String elements = lignes[i].split("\\.");


Tu devrais aller nettement plus vite
Messages postés
6413
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
17 mai 2018
286
Pour la dernière commande, il y a une erreur :

String[]
elements = lignes[i].split("\\.");
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013

Merci, je vais essayer ça et je te tiens au courant.
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013

A quoi correspond FIN_LIGNE ? C'est le nombre de termes par ligne ?

Pour le return, il y a une erreur : cannot convert from String to String[]

Je ne comprend pas les lignes :

String[] lignes = lignes.split("\n");
String[] elements = lignes[i].split("\\.");
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013

Plus de problème pour le return, j'avais fais une petite erreur.
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013

Je ne suis pas sur d'avoir compris. J'ai fais une deuxième fonction :
public String lecture2 (String path) {

String buffer = lire(path);
String[] lignes = buffer.split("\n");

String[] elements;

for(int i=0 ; i<count ; i++)	elements[i] = lignes[i].split("\\.");

return lignes.toString();

}

Cette fonction appelle la première fonction (celle que tu m'as donné) à laquelle j'ai ajouté une incrémentation d'un int "count" dans la boucle while pour avoir le nombre de lignes du fichier.
Ce qui est dans la boucle for n'est pas accepté :
Type mismatch : cannot convert from String to String[]

Type mismatch : cannot convert from String to String[]

Cela signifie que tu veux faire rentrer un String [] dans un String...

elements[i] = lignes[i].split("\\.");

... et c'est à cause de ceci. Ta fonction split renvoie si je ne me trompe pas un tableau de String. Or toi tu veux mettre les résultats de ton split dans une variable de type String. Donc ça coince.

--
Pylouq
(Lire le Réglement n'a jamais tué personne, au pire ça a instruit des gens.)

Au fait, tes fichiers me font penser à des fichiers au format CSV. Peux-être qu'utiliser une librairie spéciale pour ça peut être un bon plan, comme JavaCSV.


--
Pylouq
(Lire le Réglement n'a jamais tué personne, au pire ça a instruit des gens.)
Messages postés
6413
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
17 mai 2018
286
FIN_LIGNE correspond à la chaine "\n"

// Cette opération permet de découper le texte ligne par ligne (le séparateur de ligne est \n
String[] lignes = lignes.split("\n");

// Cette opération permet de découper lignes[i] en un tableau en séparant les éléments en fonction du "."
String[] elements = lignes[i].split("\\.");


NB : . est une expression régulière qui a une signification : tous les caractères, pour ne pas interpréter cette expression, il faut la bloquer avec \\.
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013

Bonjour,

merci pour les explications.

Cependant j'ai toujours des problèmes avec ce code et n'arrive pas à les résoudre.

La programme compile mais lorsque je lance l’analyse, c'est à dire ce qui correspond au code ci-dessous, j'obtiens cette erreur :
java.lang.ArrayIndexOutOfBoundsException : 1


je mets le code utilisé :

2ème fonction pour lire le code :
public String lire02 (String path) 
{
int FIN_LIGNE = 19;
StringBuilder sb = new StringBuilder();
try{
BufferedReader buff = new BufferedReader(new FileReader(path));
try {
String line;
while ((line = buff.readLine()) != null) {
sb.append(line).append(FIN_LIGNE);
count ++;
}
} 
finally {
buff.close();
}
} 
catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}


1ère fonction pour lire le code (qui appelle la 2ème) :
public String[] lire (String path) {

String buffer = lire02(path);
String[] lignes = buffer.split("\n");

String[] elements = new String[count * 19];

for(int i=0 ; i<count * 19 ; i++)
{
elements = lignes[i].split(",");
}
return lignes;

}


Fonction pour afficher les résultats dans une Jtable :
Object[][] data = {	{analyse.lire(nomFichier)[0], analyse.lire(nomFichier)[1], analyse.lire(nomFichier)[2], analyse.lire(nomFichier)[3], analyse.lire(nomFichier)[4], analyse.lire(nomFichier)[5], analyse.lire(nomFichier)[6], analyse.lire(nomFichier)[7], analyse.lire(nomFichier)[8], analyse.lire(nomFichier)[9], analyse.lire(nomFichier)[10], analyse.lire(nomFichier)[11], analyse.lire(nomFichier)[12], analyse.lire(nomFichier)[13], analyse.lire(nomFichier)[14], analyse.lire(nomFichier)[15], analyse.lire(nomFichier)[16], analyse.lire(nomFichier)[17], analyse.lire(nomFichier)[18]},
 				{analyse.lire(nomFichier)[19], analyse.lire(nomFichier)[20], analyse.lire(nomFichier)[21], analyse.lire(nomFichier)[22], analyse.lire(nomFichier)[23], analyse.lire(nomFichier)[24], analyse.lire(nomFichier)[25], analyse.lire(nomFichier)[26], analyse.lire(nomFichier)[27], analyse.lire(nomFichier)[28], analyse.lire(nomFichier)[29], analyse.lire(nomFichier)[30], analyse.lire(nomFichier)[31], analyse.lire(nomFichier)[32], analyse.lire(nomFichier)[33], analyse.lire(nomFichier)[34], analyse.lire(nomFichier)[35], analyse.lire(nomFichier)[36], analyse.lire(nomFichier)[37]},
 				{analyse.lire(nomFichier)[38], analyse.lire(nomFichier)[39], analyse.lire(nomFichier)[40], analyse.lire(nomFichier)[41], analyse.lire(nomFichier)[42], analyse.lire(nomFichier)[43], analyse.lire(nomFichier)[44], analyse.lire(nomFichier)[45], analyse.lire(nomFichier)[46], analyse.lire(nomFichier)[47], analyse.lire(nomFichier)[48], analyse.lire(nomFichier)[49], analyse.lire(nomFichier)[50], analyse.lire(nomFichier)[51], analyse.lire(nomFichier)[52], analyse.lire(nomFichier)[53], analyse.lire(nomFichier)[54], analyse.lire(nomFichier)[55], analyse.lire(nomFichier)[56]},

};
JTable tableau = new JTable(data, title);



Code pour afficher le graphique :
for (int i=2 ; i<20000 ;i+=19)
{
double point = Double.parseDouble(analyse.lire("docTest/test1.mid")[i]);	
seriesDroit.add(i, point);
}

XYDataset xyDataset = new XYSeriesCollection(seriesDroit);
XYDataset xyDatasetGauche = new XYSeriesCollection(seriesGauche);
  
JFreeChart chart = ChartFactory.createXYLineChart
("XYLine Chart using JFreeChart", "Différentes mesures", "Débit (l/min)", xyDataset, PlotOrientation.VERTICAL, true, true, false);
  
JFreeChart chartGauche = ChartFactory.createXYLineChart
("XYLine Chart using JFreeChart", "Différentes mesures", "Débit (l/min)",
xyDatasetGauche, PlotOrientation.VERTICAL, true, true, false);
  
  
ChartFrame frame1=new ChartFrame("XYLine Chart",chart);
ChartFrame frameGauche=new ChartFrame("XYLine Chart",chartGauche);
  	
frame1.setSize(700,500);
frameGauche.setSize(700,500);
  
frameGauche.setLocation(700,0);
  
frame1.setVisible(true);
frameGauche.setVisible(true);
Messages postés
141
Date d'inscription
samedi 4 février 2012
Statut
Membre
Dernière intervention
3 avril 2013

N'arrivant pas à m'en sortir avec le code précédent, j'ai essayé autre chose :

private int kTest = 0;
private String bufferComplet[] = new String[30000];

public String[] lire(String path)  {

    String ligne = "";
    String buffer[] = new String[19];

try {
    	BufferedReader br = new BufferedReader(new FileReader(path));
    	ligne=br.readLine();
        StringTokenizer st=new StringTokenizer(ligne, ",");
    	
        while ((ligne = br.readLine()) != null) {
            while(st.hasMoreTokens()){
            	
            	bufferComplet[kTest] = st.nextToken();
        System.out.println("buffer " + kTest + " : " + bufferComplet[kTest]);
            	kTest++;
            }
        }
    br.close();
}
catch (Exception e){
e.printStackTrace();
}
return bufferComplet;
}



Mon problème est que c'est toujours la première ligne du fichier qui s'affiche lorsque, dans la boucle while, je fais :
System.out.println("buffer " + kTest + " : " + bufferComplet[kTest]);


Quelqu'un sait-il pourquoi ?

Le problème vient du fait que ton StringTokenizer est instancié avec la première ligne lue. Même si tu effectues des readLine et que ta variable ligne est modifiée, cela ne va pas changer pour autant la ligne traitée par st. Donc soit tu en recréés un (de StringTokenizer) dans ta boucle (juste sous ton premier while) ou alors tu vois si tu peux changer la valeur de la ligne qu'il traite avec une méthode du genre setText par exemple. Je te laisse jetter un coup d'oeil dans l'API pour ça. C'est cette méthode que je préfère qui est un peu plus optimisée.

--
Pylouq
(Lire le Réglement n'a jamais tué personne, au pire ça a instruit des gens.)

Alors, où en es-tu dans ton code ?


--
Pylouq
(Lire le Réglement n'a jamais tué personne, au pire ça a instruit des gens.)