Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Entrée/Sortie Java Discussion :

Remplir une Arraylist à partir d'un fichier csv


Sujet :

Entrée/Sortie Java

  1. #1
    Candidat au Club
    Remplir une Arraylist à partir d'un fichier csv
    Bonjour tout le monde
    Je débute en Java et je suis entrain de faire un petit projet, mais j'ai un petit problème..
    Je sais remplir une Arraylist "manuellement" c'est à dire directement dans le programme, mais comment est-il possible de la remplir à partir d'un fichier CSV ?
    Je détail : supposons que le fichier soit sous forme : String1, String2, String3, String4 (etc)
    Je n'arrive pas à comprendre comment dire que le String1 (par exemple) correspond à une telle variable, comme le "nom" par exemple.. Quelqu'un pourrait m'aider svp ? J'ai cherché dans plusieurs sites/forums mais franchement je n'y arrive toujours pas..

  2. #2
    Modérateur

    Hello,

    Citation Envoyé par Sara_hda Voir le message
    Je n'arrive pas à comprendre comment dire que le String1 (par exemple) correspond à une telle variable, comme le "nom" par exemple..
    Comme ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    monObjet.nom = lesStrings[0];


    Mais si tu as des questions plus précises et qui montrent plus de code Java, n'hésite pas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Candidat au Club
    Comme ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    monObjet.nom = lesStrings[0];


    Ahhh donc, si j'ai bien compris, Java reconnait automatiquement (si je puis dire) que String[0] correspond à la "première colonne" de mon fichier CSV, qui se terminera à l'arriver du premier SEPARATOR ? et ainsi de suite ?

  4. #4
    Modérateur

    Non, mais Java donne tout ce qu'il faut pour lire un fichier ligne par ligne, et tout ce qu'il faut pour découper une String composée de plusieurs champs séparés par un séparateur.

    Il y a donc toutes les briques nécessaire et plus qu'à programmer.
    Et sauf erreur de ma part, tu as seulement demandé comment faire pour que une fois que tu as tes String1, string2, String3 etc tu puisses faire en sorte que String1 aille dans quelque part qui s'appelle nom.
    Je t'ai donc dit comment on fait ça, pas comment on fait autre chose que ça.

    Pour lire les lignes d'un fichier :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List<String> lireLignes(String nomFichier) throws IOException {
      Path path = Paths.get(nomFichier);
      return Files.readAllLines(nomFichier, StandardCharsets.UTF_8);
    }


    Pour séparer les champs d'une String :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    String maString = "champ1, champ2, champ3, champ4";
     
    String[] champs = maString.split(", ");
    System.out.println(champs[0]);
    System.out.println(champs[1]);
    System.out.println(champs[2]);
    System.out.println(champs[3]);
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Candidat au Club
    Merci pour ton explication.
    Si j'ai bien compris ca devrait donner un truc de ce genre : (j'ai utilisé un BufferedReader plutôt)
    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
     public static ArrayList<Country> ReadFile(String pathToFile){
    	    	String country;
     
    	    	ArrayList<Country> countries = new ArrayList<Country>();
     
     
     
    	    	try {
    		            BufferedReader reader = new BufferedReader(new FileReader(new File(pathToFile)));
    		            boolean ligne;
     
     
    		            while(ligne = reader.readLine() != null){
     
    		            	String maString = "number,countryName, surface";
     
    		            	String[] champs = maString.split("\t ");
    		            	System.out.println(champs[0]);
    		            	System.out.println(champs[1]);
    		            	System.out.println(champs[2]);
    		            	Country.countryName = champs[1];
    		    	    	Country.surface = champs[2];
    		            }
     
    			 }
    		         catch (Exception ex){
    		            System.err.println("Error. "+ex.getMessage());
    		        }
    	    	ArrayList<Country> getCountries(){
    	    		return countries;
    	    	}
    	    }
    		public static void main(String[] args){
     
     
    			ReadFile("/Users/dell/Desktop/Cours/JAVA/Projet/rawdata_2147.csv");
    	    }
     
    }

  6. #6
    Modérateur

    Salut,

    Déjà, ligne c'est une String, pas un boolean !

    String maString = "number,countryName, surface";
    Oui, enfin, si tu lis des lignes dans le fichier, c'est ces lignes que tu dois traiter avec le split, pas une ligne en dur, sinon tu auras les valeurs de cette String dans ton résultat final... Donc c'est String[] champs = ligne.split(...).

    Ensuite :
    String[] champs = maString.split("\t ");
    Il ne faut pas mettre n'importe quoi en paramètre en split : il faut mettre un séparateur qui correspond à ce qui sert de séparateur de mots dans les lignes du fichier. "\t " signifie que tes mots sont séparés par une tabulation suivie d'une espace, systématiquement. Déjà, ce n'est pas le cas dans ta chaîne exemple "number,countryName, surface", dont le séparateur est une virgule, ou une virgule suivie d'une espace, autrement dit une virgule suvie d'un certains nombres d'espaces, on pourrait dire de 0 à n, donc on aurait split(", *"), ou si on veut dire zéro ou une espace maxi, split(", ?").

    Quant à ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    Country.countryName = champs[1];
    Country.surface = champs[2];

    veux dire à priori que les attributs de la classe Country sont "static" : tous tes pays auront les mêmes valeurs, et la liste ne contiendra aucun pays.
    Il faut avoir des attributs non static, utiliser plutôt des mutateurs par attribut ou le contructeur de Country, créer une instance de Country par ligne du fichier, et l'ajouter ensuite à l'ArrayList (méthode add).
    A noter qu'il faut également fermer le BufferedReader après l'avoir lu (voir try-with-resource).

    Et le ArrayList<Country> getCountries(){ n'a rien à faire là où il se trouve...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Candidat au Club
    Citation Envoyé par joel.drigo Voir le message


    String[] champs = maString.split("\t ");
    Il ne faut pas mettre n'importe quoi en paramètre en split : il faut mettre un séparateur qui correspond à ce qui sert de séparateur de mots dans les lignes du fichier. "\t " signifie que tes mots sont séparés par une tabulation suivie d'une espace, systématiquement.
    Désolée, je m'étais trompée dans ma chaîne d'exemple, mais le fichier sépare bien les "colonnes" par une tabulation


    Quant à ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    Country.countryName = champs[1];
    Country.surface = champs[2];

    veux dire à priori que les attributs de la classe Country sont "static" : tous tes pays auront les mêmes valeurs, et la liste ne contiendra aucun pays.
    Exactement, enfaite j'ai suivi ce que la personne juste avant toi m'avait dit, et cela m'a emmené à des erreurs où Eclipse me proposait de modifier le statut de mes variables en "static", ce que je ne comprenais pas, ce n'est pas logique..Du coup je sais pas comment faire, tu pourrais m'orienter stp ?


    Il faut avoir des attributs non static, utiliser plutôt des mutateurs par attribut ou le contructeur de Country, créer une instance de Country par ligne du fichier
    Je pourrais faire ca comment ? Désolée je l'impression d'être vraiment nulle, mais j'aimerai vraiment comprendre xD

    Quant à cela :

    et l'ajouter ensuite à l'ArrayList (méthode add).
    Cette méthode ne sert pas uniquement à ajouter "manuellement" des pays ? c'est à dire sans avoir recours à des fichiers externes ?


    Et le ArrayList<Country> getCountries(){ n'a rien à faire là où il se trouve...
    Je suis totalement d'accord mais je ne savais absolument pas où le mettre.. :/

  8. #8
    Modérateur

    Citation Envoyé par Sara_hda Voir le message
    Désolée, je m'étais trompée dans ma chaîne d'exemple, mais le fichier sépare bien les "colonnes" par une tabulation
    Dans ce cas-là,
    1. ce n'est pas un fichier CSV (comma-separated values), mais un TSV (tab-separated values) ;
    2. on fait split("\t"), sans espace.


    Citation Envoyé par Sara_hda Voir le message

    Exactement, enfaite j'ai suivi ce que la personne juste avant toi m'avait dit, et cela m'a emmené à des erreurs où Eclipse me proposait de modifier le statut de mes variables en "static", ce que je ne comprenais pas, ce n'est pas logique..Du coup je sais pas comment faire, tu pourrais m'orienter stp ?
    Mmm je ne vois pas dans ce qu'à dit @thelvin ce qui aurait pu t'ammener à ça, mais la solution donc c'est :
    1. D'avoir une classe avec des attributs, non static, avec constructeur :
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      public class Country {
           private final String name;
           private final double surface;
           public Country(String name, double surface) {
                this.name=name;
                this.surface=surface;
           }
           public String getName() {
                    return name;
           }
           public double getSurface() {
                    return surface;
           }
      }
    2. Pour le décodage et la construction :
      Code :Sélectionner tout -Visualiser dans une fenêtre à part
      1
      2
      String[] champs = maString.split("\t");
      Country country = new Country(champs[1], Double.parseDouble(champs[2]));
    3. Et pour l'ajouter à la liste


    Citation Envoyé par Sara_hda Voir le message

    Je suis totalement d'accord mais je ne savais absolument pas où le mettre.. :/
    C'est probablement que tu n'en as pas besoin alors. Elle servirait dans le cadre d'une classe qui a un attribut de type ArrayList par exemple, ou convertible vers ce type...
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Exemple {
           private ArrayList<Country> countries;
           public Exemple(String path) {
                  countries=Loader.readFile(path); // ici on appelle l'autre méthode, celle qui charge le fichier dans la liste
           }
           public ArrayList<Country> getCountries() {
                  return countries;
           }
    }

    En tout cas, on ne met jamais une déclaration de méthode en plein milieu d'une méthode.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #9
    Candidat au Club
    Ce message n'a pas pu être affiché car il comporte des erreurs.

  10. #10
    Modérateur

    Si tu n'as pas la possibilité de lire tous les fichiers en une seule passe, en parallèle donc, ce qui te permettrait d'avoir toutes les informations nécessaires à la création d'un pays en un seul appel,

    1. soit tu t'arranges pour construire d'abord un seul fichier comme la fusion, ce qui réduit le problème au cas "j'ai toutes les informations pour créer un pays en une seule fois"
    2. soit tu prévois d'avoir des attributs mutables. Pas besoin de les prévoirs nécessairement dans le constructeur, mais il faut au moins avoir une méthode de mutation.
      Par exemple
      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
      public class Country {
       
          private final String name;
          private final double surface;
          private int population;
       
          public Country(String name, double surface) {
               this.name=name;
               this.surface=surface;
          }
       
          public Country(String name, double surface, int population) {
               this(name,surface);
               setPopulation(population);
          }
       
          public String getName() {
              return name;
          }
       
          public double getSurface() {
              return surface;
          }
       
          public int getPopulation() {
              return population;
          }
       
          public void setPopulation(int population) {
              this.population=population;
          }
       
      }

      Tu peux rendre tout mutable si tu veux, mais ça veut dire qu'on peut facilement modifier une valeur et que le programme fasse n'importe quoi. Eventuellement, tu peux rendre non mutable le nom (il y a peu de chance que le nom change pendant l'exécution du programme), ce qui te permettra par exemple de facilement t'en servir comme clef dans une Map (ce qui est peut être plus qu'utile lors du chargement des autres fichiers), et laisser le reste mutable.
    3. Il y a différents autres moyens de faire (fabriques, proxy, etc.) mais ils sont un peu plus compliqués surtout pour un débutant. Ce n'est pas indispensable de tout verrouiller : tout dépend du but final (un exercice, une API ou une véritable application).



    Citation Envoyé par Sara_hda Voir le message
    Une dernière question : Pour afficher le contenu de mon Arraylist, je dois utiliser la méthode String toString ?
    Ça dépend. Il y a une infinité de façons d'afficher une liste. Si tu fais System.out.println( countries ); dans la méthode ReadFile (juste avant le return) ça utilisera en effet (implicitement) la méthode toString() de ArrayList pour afficher la liste dans la sortie standard. En revanche, pour que les pays s'affichent de manière lisible en utilisant ce moyen, il faudra redéfinir la méthode toString() de country.
    Par exemple, pour qu'il n'y ait que le nom qui s'affiche :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Country {
     
            /**...tout le reste qu'on a déjà mis...**/
     
           public String toString() {
                  return name; 
           }
     
    }


    ou, en construisant une chaîne plus complexe par concaténation pour afficher autre chose

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Country {
     
            /**...tout le reste qu'on a déjà mis...**/
     
           public String toString() {
                  return "["+name+", surface="+surface+", pop="+population+"]"; 
           }
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Candidat au Club
    Citation Envoyé par joel.drigo Voir le message
    Si tu n'as pas la possibilité de lire tous les fichiers en une seule passe, en parallèle donc, ce qui te permettrait d'avoir toutes les informations nécessaires à la création d'un pays en un seul appel,
    Justement, je voulais lire tous les fichiers d'un coup d'un seul, mais je ne pensais pas ça possible ! Tu pourrais m'aider sur ce point aussi ? xD

  12. #12
    Modérateur

    Si on sait lire un fichier, on sait en lire plusieurs, par exemple ici j'ouvre 2 flux :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try(BufferedReader reader1 = Files.newBufferedReader(Paths.get( "c:/truc/fichier1.txt" ));
    BufferedReader reader2 = Files.newBufferedReader(Paths.get("c:/truc/fichier2.txt")) {
     
       // on a 2 readers, un sur chaque fichier
     
    }


    Le problème se situe plutôt au niveau de :
    1. est-on sûr de pouvoir les lire les deux de concerts (si le nombre de lignes de l'un dépend de l'autre (comme par exemple, s'ils ont le même nombre de lignes)).
    2. Cela peut devenir compliqué selon le format (si les données ne sont pas dans le même ordre par exemple...)
    3. bien gérer le fait qu'on ne peut pas être sûr que des fichiers soient correctement constitués : as-t-on un moyen de détecter le fait que cela ne soit pas le cas, pour éviter d'exécuter le programme avec des données foireuses, ou de laisser lamentablement planter le programme pendant la lecture des fichiers sans savoir pourquoi

      Par exemple, si on a dans les deux fichiers, des lignes de champs identifiables (CSV, TSV, ou du genre), et qu'on a la même information extractible (le nom du pays dans les deux par exemple), et que ces données sont bien dans le même ordre, on peut comparer :

      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
      try(BufferedReader reader1 = Files.newBufferedReader(Paths.get( "c:/truc/fichier1.txt" ));
      BufferedReader reader2 = Files.newBufferedReader(Paths.get("c:/truc/fichier2.txt")) {
       
         for(String line1=reader1.readLine(); line1!=null; line1=reader1.readLine()) {
       
                String line2 = reader2.readLine();
                if ( line2==null ) {
                        // j'ai une ligne dans mon fichier 1, mais pas dans mon fichier 2 : erreur
                       throw new IOException("Fichier 2 trop court");
                }
       
                String[] champLine1 = line1.split("\t"); // je lis les champs dans le fichier 1 (séparés par des tab)
                String country = champLine1[0]; // le pays est en première position
       
                String[] champLine2 = line2.split(" "); // je lis les champs dans le fichier 2 (ceux-là sont séparés par des espaces)
                if ( champLine2[1].equals(country) ) { // le pays est en deuxième position dans le fichier 2
                     // c'est bien le même pays dans les deux lignes...
                }
                else {
       
                    // erreur...
       
                }
       
       
         }
       
      }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  13. #13
    Candidat au Club


    Par exemple, si on a dans les deux fichiers, des lignes de champs identifiables (CSV, TSV, ou du genre), et qu'on a la même information extractible (le nom du pays dans les deux par exemple), et que ces données sont bien dans le même ordre, on peut comparer :
    Les champs sont biens identifiables même si différents, mais comme tu me l'as détaillé, là n'est pas le problème. Après oui, le nom du pays est présent dans les 3 fichiers que j'ai, mais le problème c'est qu'il ne se trouve pas forcément à la même place dans chaque fichier.. :/ Est ce contournable ?

    Après, il y a certains fichiers plus long que d'autres mais toutes les informations "utiles" sont présentes dans tous les fichiers, je veux dire, que tous les pays sont présents dans les 3 fichiers, certains sont plus long de part des informations que je ne veux pas extraire donc cela ne pose pas de problème :-)

  14. #14
    Modérateur

    Citation Envoyé par Sara_hda Voir le message
    Les champs sont biens identifiables même si différents, mais comme tu me l'as détaillé, là n'est pas le problème. Après oui, le nom du pays est présent dans les 3 fichiers que j'ai, mais le problème c'est qu'il ne se trouve pas forcément à la même place dans chaque fichier.. :/ Est ce contournable ?
    Justement, je t'ai mis dans mon exemple, un cas où le pays n'est pas à la même place dans les deux fichiers (dans la première colonne dans l'un et dans la deuxième dans l'autre) !

    Citation Envoyé par Sara_hda Voir le message

    Après, il y a certains fichiers plus long que d'autres mais toutes les informations "utiles" sont présentes dans tous les fichiers, je veux dire, que tous les pays sont présents dans les 3 fichiers, certains sont plus long de part des informations que je ne veux pas extraire donc cela ne pose pas de problème :-)
    S'il y a un moyen relativement simple d'ignorer ces informations, ça ne pose pas de problème en effet.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  15. #15
    Candidat au Club
    Citation Envoyé par joel.drigo Voir le message
    Justement, je t'ai mis dans mon exemple, un cas où le pays n'est pas à la même place dans les deux fichiers (dans la première colonne dans l'un et dans la deuxième dans l'autre) !
    Ah oui, autant pour moi !
    D'ailleurs, si par exemple dans le fichier1, disons la Russie (et toutes les informations la concernant) se trouve sur la 5ème ligne du fichier, mais sur la 25ème du fichier2.. Ca ne pose pas de problème ? Le bout de code que tu m'as envoyé ne compare pas la premiere ligne du fichier1 avec la premiere ligne du fichier2 ? Elle est bien comparée à toutes les lignes du fichier2 jusqu'à retrouver la Russie (pour cet exemple)

  16. #16
    Modérateur

    Citation Envoyé par Sara_hda Voir le message

    D'ailleurs, si par exemple dans le fichier1, disons la Russie (et toutes les informations la concernant) se trouve sur la 5ème ligne du fichier, mais sur la 25ème du fichier2.. Ca ne pose pas de problème ? Le bout de code que tu m'as envoyé ne compare pas la premiere ligne du fichier1 avec la premiere ligne du fichier2 ?
    Bah si justement, je disais bien "si les pays sont dans le même ordre" dans les deux fichiers, ou s'il y a une dépendance entre le nombre de lignes dans le fichier 2 et le fichier 1), comme par exemple si les fichiers ont le même nombre de lignes, ou si le fichier 2 a 5 fois plus de lignes que le premier et que l'information à lire se trouve bien toutes les 5 lignes... (peu importe s'il y a un offset, il faut juste une régularité), ou s'il y a un autre moyen de déterminer (par exemple, on peut imaginer qu'il y a un token identifiable qui sert de marqueur, et donc il suffit de lire jusqu'à ce marqueur).
    On pourrait facilement le faire également si tous les pays se trouve dans le fichier 2, mais pas tous dans le fichier 1, tant que l'ordre des pays est le même dans les deux :

    Citation Envoyé par Sara_hda Voir le message
    Elle est bien comparée à toutes les lignes du fichier2 jusqu'à retrouver la Russie (pour cet exemple)
    Donc absolument pas ! Dans mon exemple, si tu n'as pas les mêmes données dans les deux lignes lues 2 à 2, on signale une erreur (et on devrait arrêter le traitement)

    Il faudrait faire éventuellement (et c'est toujours dans les conditions que les fichiers soient triés dans le même ordre ) :
    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
    for(String line1=reader1.readLine(); line1!=null; line1=reader1.readLine()) {
     
     
              String[] champLine1 = line1.split("\t"); // je lis les champs dans le fichier 1 (séparés par des tab)
              String country = champLine1[0]; // le pays est en première position
     
              String[] champLine2=null;
              for(String line2=reader2.readLine(); line2!=null; line2=reader2.readLine()) {
     
     
                         String[] champs = line2.split(" "); // je lis les champs dans le fichier 2 (ceux-là sont séparés par des espaces)
                         if ( champs[1].equals(country) ) { // le pays est en deuxième position dans le fichier 2
                             // c'est bien le même pays dans les deux lignes...
                             champLine2 = champs; // on récupère la ligne
                             break; // on arrête la lecture du fichier
                         }
              }
              if ( champLine2==null ) {
                  // on n'a pas trouvé le pays dans le fichier 2 : erreur
                  throw new IOException("Erreur !!!");
              }
     
              // on peut exploiter ici les données dans champLine1 et champLine2.
     
       }


    Si tu n'as pas cet ordre identique garanti, à part lire plusieurs fois le fichier, ce qui n'est pas le plus performant, il vaut mieux lire les fichiers séparement (le premier dans une Map pour retrouver plus facilement/rapidement les pays lors de la lecture des autres), sauf si les fichiers sont trop énormes pour la mémoire (dans ce cas, il faudra lire les fichiers plusieurs fois, ou éventuellement utiliser un accès direct, ce qui amènera d'autres problèmes).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  17. #17
    Candidat au Club


    Si tu n'as pas cet ordre identique garanti, à part lire plusieurs fois le fichier, ce qui n'est pas le plus performant, il vaut mieux lire les fichiers séparement (le premier dans une Map pour retrouver plus facilement/rapidement les pays lors de la lecture des autres), sauf si les fichiers sont trop énormes pour la mémoire (dans ce cas, il faudra lire les fichiers plusieurs fois, ou éventuellement utiliser un accès direct, ce qui amènera d'autres problèmes).
    N'est-il pas possible de récupérer le nom du pays présent dans le fichier1 et d'en faire une recherche dans le 2nd. Faire une truc du genre :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     for( line2=reader2.readLine(); line2!=null; line2=reader2.readLine()) {
                    while(champs[1] != country){
                           line2++;
                   }
                 champs[2]=champs;
                }

    Est-ce correcte ?

  18. #18
    Modérateur

    Je te montre justement une recherche dans mon dernier code, mais je te dis que si les fichiers ne sont pas triés dans le même ordre, il faut relire le fichier, sous-entendu, le fermer, le réouvrir pour le relire depuis le début, parce qu'un Reader consomme le flux qu'il lit !!!, ce qui veut dire potentiellement plusieurs lectures du fichier (on pourrait siouxer pour le faire que si on trouve pas à la fin du fichier, on ferme, on réouvre, et on recommence au début, en gérant une sorte de fichier rotatif). On peut tout faire, simplement, parfois c'est simple, parfois c'est plus complexe (on cherche à éviter que le code devienne une usine à gaz), parfois c'est rapide, parfois c'est plus lent (on cherche à éviter de prendre des heures à traiter alors qu'on peut le faire en quelques millisecondes).

    En revanche, ça
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    while(champs[1] != country){

    n'est pas correcte. On teste toujours l'égalité de String avec la méthode equals().

    Quant au reste, rien que le line2++ ! line2 c'est une chaîne de caractères : qu'espères-tu faire en faisant line2++ ?
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  19. #19
    Candidat au Club
    Je te remercie pour ton explication, je pense avoir compris :-)

    Je travaille sous Eclipse, et en faisant un test, il m'affiche "Error.1"
    Quelqu'un saurait pourquoi ?

  20. #20
    Modérateur

    C'est tout ce qu'il t'affiche ? Aussi, montre-nous le code !
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.