# Exploiter des fichiers texte en Java



## macErmite (5 Février 2006)

Bonjour,

Je recherche, en programmation java, à exploiter un fichier texte. 

   Celui-ci contient des données numériques ainsi que des lettres. En fait il s'agit d'un catalogue. Je ne comprends pas comment choisir une ligne particulière pour extraire des données particulières placées dans celle-ci.

   Dans l'extrait joint à ce message chaque ligne commence par le nom d'un matériel, puis toutes les données pour celui-ci. Un saut de ligne passe au matériel suivant, ainsi de suite ...

Dans cet extrait il y en a deux, une ligne pour "S-BAH10 " puis une autre pour "S-BAH11". Mais dans le fichier original il y en a plus de 100 :love: 

Merci pour vôtre collaboration

macErmite


----------



## mpergand (5 Février 2006)

Fastoche


----------



## macErmite (5 Février 2006)

J'ai bien téléchargé le fichier Zip, mais je suis tellement novice que je ne sais pas comment exploiter tous ces documents :rose:


----------



## macErmite (11 Février 2006)

Grâce a t on aide, j'ai repris quelques essais. Cela semble fonctionner.

Maintenant je suis bloqué car j'ai créé un délimiteur "  ", seulement j'ai des chaînes dans ce fichier qui ont cette forme :

1.38464579-1 1.21988043   9.32734340-3 4.27498654-2          1.19251777 2 1.59034337   1.38464579-1 1.21988043   9.32734340-3 4.27498654-2 1.19251777 2 

Etant donné le nombre de lignes, +163, j'aimerais construire une fonction permettant de réécrire ce fichier texte pour obtenir :

1.38464579 -1 1.21988043   9.32734340 -3  4.27498654 -2 1.19251777 2 1.59034337   1.38464579 -1 1.21988043   9.32734340 -3 4.27498654 -2 1.19251777 2 

C'est à dire inserer un espace lorsque le signe - est présent.

L'on peut biensûr le faire dans le fichier texte avec un éditeur de texte, mais cela serait dommage de ne pas passer par Java, n'est-ce pas ?


Voilà ou j'en suis :



```
import java.io.*;
import java.util.*;

public class essai {

    public static void main (String args[ ]) throws IOException{
     
/**
Compte le nombre de lignes contenus dans le fichier texte
*/

BufferedReader test = new BufferedReader (new FileReader("essais.txt"));

int compteur =0;
String ligne;

    while ((ligne=test.readLine()) != null)
                {
                compteur=compteur+1;
                }
    
test.close();

/**

Recherche le type de verre dans le fichier texte, si celui-ci est trouvé
w=1, si la recherche ligne par ligne est infructueuse la recherche est arrétée grace au compteur de ligne

*/
String verre="rien";
try
{    
    BufferedReader in = new BufferedReader (new FileReader("essais.txt"));
    
    
    int w=0;
    int compteur_ligne = 0;
    while (w == 0 & compteur_ligne != compteur)
        {
            String s = in.readLine();
            
            StringTokenizer t = new StringTokenizer(s," ");//déliminateut : espace
                        
            verre=t.nextToken();
            
            if (verre.equals("S-BAH11"))
                {w = 1;
                System.out.println("Localisation du verre "+verre);
                
                    for (int i=1; i<=63;i++)
                        {
                        double indice = Double.parseDouble(t.nextToken());
                        }
                }
            compteur_ligne = compteur_ligne +1;
                
            
            if (compteur_ligne ==compteur & w==0)
                {
                System.out.println("Aucun verre ne correspond a votre critere de recherche");
                verre="rien";
                }
        }
    in.close();
}
catch(IOException exception)
{
exception.printStackTrace();
}

System.out.println("Travail avec  "+verre);

 


        
}
}
```


----------



## mpergand (11 Février 2006)

Salut,

nextToken retourne un String, donc pas de problème pour tester si un caractère donné est présent:


```
String s=t.nextToken();
int index=s.indexOf('-')  // recherche la première occurence de '-' dans la chaine
if(index!=-1)
  {
  // y a un '-' à la position index
  
  }
else
  {
  // y a pas de '-'
  }
```


----------



## macErmite (12 Février 2006)

J'ai essayé cette possibilité d'utiliser indexOf("-"), apparement la détection se fait qu'une seule fois 


exemple de Token analysé (" " est le délimiteur):

Indice de ce verre 1.7879-0.0069-0.0002-0.0027-0.0024-0.0156 avec l'espace
le signe (-) est en position6
y a un '-' a la position index


----------



## macErmite (12 Février 2006)

Voilà ou j'en suis :

-------------------------------------------------


```
public class essais {

    public static void main (String args[ ]) throws IOException{
     
/**
Compte le nombre de lignes contenu dans le fichier texte
*/
BufferedReader test = new BufferedReader (new FileReader("essais.txt"));

int compteur =0;
String ligne;

    while ((ligne=test.readLine()) != null)
                {
                compteur=compteur+1;
                }
    //System.out.println(compteur);

test.close();
/**

Recherche le type de verre dans le fichier texte, si celui-ci est trouvé
w=1, si la recherche ligne par ligne est infructueuse la recherche est arrétée grace au compteur de ligne

*/
String verre="rien";
try
{    
    BufferedReader in = new BufferedReader (new FileReader("essais.txt"));
    
    
    int w=0;
    int compteur_ligne = 0;
    while (w == 0 & compteur_ligne != compteur)
        {
            String s = in.readLine();
            
            StringTokenizer v = new StringTokenizer(s," ");//délimiteur : espace
                        
            verre=v.nextToken();
            
            
            
            if (verre.equals("S-BAH11"))
                {w = 1;
                System.out.println("Localisation du verre "+verre);
                
                    for (int i=1; i<=63;i++)
                        {
                        String indice = v.nextToken();
                    
                        System.out.println("Token "+ indice);
                        int index=indice.indexOf("-");  // recherche la première occurence de '-' dans la chaine
                        if(index!=-1)//si index est different de -1 --> renvoie -1 si il ne trouve pas de (-)
                            {
                            System.out.print("Detection de (-) a la position index : "+index);
                            System.out.print("  et taille du Token : " + indice.length());
                            System.out.println(" , affichage du token tronque apres le signe (-) : " + indice.substring(index, indice.length()));
                                                                            
                            }
                        else
                            {
                            //System.out.println("y a pas de '-'");
                            }
                                                                }
                }
            compteur_ligne = compteur_ligne +1;
                
            
            if (compteur_ligne ==compteur & w==0)
                {
                System.out.println("Aucun verre ne correspond a votre critere de recherche");
                verre="rien";
                }
        }
    in.close();
}
catch(IOException exception)
{
exception.printStackTrace();
}

System.out.println("Travail avec  "+verre);

 


        
}
}
```

-------------------------------------------------


Ce qui donne :
(...)

Token 0.4747
Token 1.3048
Token 0.8050
Token 0.4846
Token 0.5154
Token 1.7879-0.0069-0.0002-0.0027-0.0024-0.0156
Detection de (-) a la position index : 6  et taille du Token : 41 , affichage du token tronque apres le signe (-) : -0.0069-0.0002-0.0027-0.0024-0.0156
Token 1.57138860
Token 1.47869313-1
Detection de (-) a la position index : 10  et taille du Token : 12 , affichage du token tronque apres le signe (-) : -1

(...)


-------------------------------------------------

En fait, il faudrait pousser le recherche de (-) à l'intérieur du Token et ne pas s'arreter au premier signe (-).


----------



## mpergand (12 Février 2006)

Jette un il sur la doc, ça peut servir  
En particulier pour String, il existe une méthode géniale qui te permet de spécifier une position pour le début de la recherche:


> indexOf(int ch, int fromIndex)
> Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.



Incroyable isn't it  

Sinon tu peux utiliser un 2e tokenizer:

```
try
		{
		textFile=new File("../../ExtraitCatalogue.txt");
		BufferedReader reader=new BufferedReader(new FileReader(textFile));
		String line;
		
		while((line=reader.readLine())!=null)
			{
			StringTokenizer lineParser=new StringTokenizer(line);
			String item=lineParser.nextToken();
			catalogueFrame.append(item+"\n");
			while(lineParser.hasMoreTokens()==true)
				{
				String num=lineParser.nextToken();
/*
		pour récupérer une valeur numérique, utiliser la méthode 'parse' :
			float f=Float.parseFloat(num);
		ou	int i=Integer.parseInt(num);
		etc

*/
				
				StringTokenizer numParser=new StringTokenizer(num,"-");
				while(numParser.hasMoreTokens()==true)
					{
					catalogueFrame.append("\t"+numParser.nextToken());
					}
						
				catalogueFrame.append("\n");
				}
			}
		}
	catch(Exception ex)
		{
		System.out.println(ex);
		}
```

Code à remplacer dans le fichier CatalogueParser.zip donné plus haut


----------



## macErmite (15 Février 2006)

Y a un probleme à utiliser deux StringTokenizer durant ces procédures, car une deuxième définition de StringTokenizer créée une lecture, de nouveau au début de la ligne enregistré dans la variable String.


----------



## Anabys (16 Février 2006)

Il est possible d'utiliser les expressions régulières avec les String. C'est plus puissant que les tokenizer si tu dois parcourir ton fichier selon plusieurs critères.


----------



## OlivierL (16 Février 2006)

Au fait, question conne, mais bon...
As-tu ton mot à dire sur le format de ce fameux fichier texte ?

Si oui, et ben ca sera pas mal que ce soit du XML.
L'intérêt majeur de XML étant que toutes les plateformes de développement disposent d'API puissante pour sa manipulation.


----------



## macErmite (16 Février 2006)

Non, il s'agit d'un fichier téléchargé sur un site internet

Je vais essayé la solution avec les expressions régulières sur les String

...


----------



## macErmite (18 Février 2006)

Je suis actuellement en train de tester la fonction find(). Celle-ci prend la forme suivante :

Pattern modele = Pattern.compile("-");
Matcher recherche = modele.matcher(indice);
while(recherche.find())
{
System.out.println("Une occurrence a ete trouvee");
}


à suivre ...:love:


----------



## macErmite (18 Février 2006)

Avez vous déjà vue ... un programme qui marche ...

Avec ces quelques lignes, j'ai enfin réussis (grâce à vôtre aide ) à exploiter ce fameux fichier. Ce qui donne :

---------------------------------------
import java.io.*;
import java.util.*;
import java.util.regex.*;


public class essais {

	public static void main (String args[ ]) throws IOException{

/**
Compte le nombre de lignes contenu dans le fichier texte
*/
BufferedReader test = new BufferedReader (new FileReader("essais.txt"));

int compteur =0;
String ligne;

	while ((ligne=test.readLine()) != null)
				{
				compteur++;
				}
	//System.out.println(compteur);

test.close();
/**

Recherche le type de verre dans le fichier texte, si celui-ci est trouvé
w=1, si la recherche ligne par ligne est infructueuse la recherche est arrétée grace au compteur de ligne

*/
String verre="rien";
try
{	
	BufferedReader in = new BufferedReader (new FileReader("essais.txt"));


	int w=0;
	int compteur_ligne = 0;
	while (w == 0 & compteur_ligne != compteur) //w1
	{
			String s = in.readLine();
			boolean returnTokens=false;

			StringTokenizer v = new StringTokenizer(s," ");//délimiteur : espace

			verre=v.nextToken();

			if (verre.equals("S-BAH11"))
				{w = 1;
				System.out.println("Localisation du verre "+verre);
				/**
				while = execute cette instruction tant que cette condition est vraie, ne s'execute jamais si la condition
				est fausse.

				v.hasMoreTokens() = renvoie true si il reste des Token à analyser

				equals = test d'égalité avec deux String
				*/
					while(v.hasMoreTokens()==true)//w2
					{
						String indice = v.nextToken();
						int longueur = indice.length();
						System.out.println("Token "+ indice + " taille Token = "+longueur);


						Pattern modele = Pattern.compile("-");
						int compteur_find=0;
						Matcher recherche = modele.matcher(indice);

									while(recherche.find())
									{
									compteur_find++;
									//System.out.println("Le texte \"" + recherche.group() +"\" debute a " + recherche.start() + " et termine a " +recherche.end()); 
									}
									//System.out.println("nombre d'occurence :"+compteur_find);

						int compteurFind[]=new int [compteur_find+1];		
						int indexFind[]=new int [compteur_find+2];

						{int i=1;

						Pattern modeleNew = Pattern.compile("-");
						Matcher rechercheNew = modeleNew.matcher(indice);

									while(rechercheNew.find())
									{
									indexFind_= rechercheNew.start();
									//System.out.println("IndexFind ["+i+"] ="+indexFind);
									i++;
									}
						}

						indexFind[0]=0;
						indexFind[compteur_find+1]=indice.length();

						if (indexFind[1]==0)
						{
						indexFind[1]=1;
						}

						for (int i=0 ; i <= compteur_find ; i++)
						{
						System.out.println("indice decoupe =   "+indice.substring(indexFind,indexFind[i+1]));

						}

					 } 



				 compteur_ligne = compteur_ligne +1;


			if (compteur_ligne ==compteur & w==0)
				{
				System.out.println("Aucun verre ne correspond a votre critere de recherche");
				verre="rien";
				}
		}//while
	}
	in.close();
}//try
catch(IOException exception)
{
exception.printStackTrace();
}

System.out.println("Travail avec  "+verre);






}//void main
}//class


----------------------------------


cela donne dans la fenêtre run :

(...)
Token 0.4846 taille Token = 6
indice decoupe =   0.4846
Token 0.5154 taille Token = 6
indice decoupe =   0.5154
Token 1.7879-0.0069-0.0002-0.0027-0.0024-0.0156 taille Token = 41
indice decoupe =   1.7879
indice decoupe =   -0.0069
indice decoupe =   -0.0002
indice decoupe =   -0.0027
indice decoupe =   -0.0024
indice decoupe =   -0.0156

(...)

Token 4.02401684-2 taille Token = 12
indice decoupe =   4.02401684
indice decoupe =   -2

(...)

-------------------------------------------------------


maintenant oui  :love:_


----------



## macErmite (19 Février 2006)

Vous aurez donc remarqué :mouais: qu' un fichier texte n'est apparement pas évident à manipuler. Enfin pour moi 

Je crois que je peux me procurer un fichier de type Excell, équivalent en contenu du fichier texte.

Alors reste à trouver un moyen pour lire dans les cellules les infos recherchés  

l'aventure continue ...


----------



## macErmite (25 Février 2006)

Après avoir ouvert des sites internet sur ce sujet, je commence à avoir peur  

J'ai trouvé que des applications à télécharger pour introduire des fonctions propres à ces fichiers pour lire les cellules des fichiers Excel ou autre tableur.

Impossible de tomber sur des fonctions sans ajouter ces packages de programmeurs. 

C'est une impréssion ou c'est la gue-guerre entre Sun et micro$oft ? 


PS: Pourquoi l'icone enveloppe de ce sujet, dans ce forum, est toute rouge :rose:  ?


----------



## GrandGibus (25 Février 2006)

L'enveloppe du sujet est rouge, car il a atteint un certain seuil de visualisation: il a été ouvert et lu un grand nombre de fois.

Concernant ton soucis, je pense que quoiqu'il arrive, et pour la longévité de ton programme, il vaut mieux que tu passes par ton propre format. Du texte semble être le minimum (car lisible par nous, les humains), et en XML car c'est le plus portable, et comme cité plus haut, de nombreuses librairies existent sous toutes les plateformes pour lire du XML. 

Juste pour étayer ce choix: imagine que tu développes tout ton programme autour du format Excell... et que dans 2 mois, Cro$oft décide de changer complétement leur format (en xml par exemple, c'est la rumeur)... et bien, qu'adviendra-t-il de ton programme :hein: ?


----------



## macErmite (2 Mars 2006)

OK, en attendant de maitriser les fichiers XML, je vais travailler les fichiers textes.

 He ho miracle, après avoir télécharger NeoOffice :love:  , j'ai réussis à enregistrer le fichier XLS en fichier texte. Il me demande même quel type de StringTokenizer je veux mettre dans le futur fichier texte !!

Cependant il reste quelques mystères à élucider, notament la possibilité d'enregistrer de nouvelles données dans un fichier texte sans pour autant tout éffacer ?

 A ce jour, lorsque je veux enregistrer des données celles-ci éffacent le fichier d'origine  !!



Une idée ?? :mouais:


----------

