IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Java Discussion :

Découpage d'un fichier texte en java.


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Février 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Février 2017
    Messages : 4
    Par défaut Découpage d'un fichier texte en java.
    Bonjour,

    Je cherche à découper un fichier extension en plusieurs fichiers selon la valeur d'une ligne, je me suis totalement inspiré d'un poste équivalent, mais je n'arrive pas à générer autant de fichier qu'attendu.

    Ci-joint le code :
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
     
    public class Eclatement {
    	private static File destDir;
    	private static BufferedReader reader;
    	private static File file;
     
    	public static File[] splitFile(String filePath, String toDir)
    			throws IOException {
    		handleToDir(toDir);
    		File[] splittedFiles;
    		List<File> files = new ArrayList<File>();
    		reader = new BufferedReader(new FileReader(filePath));
    		String fileName = new File(filePath).getName();
    		StringBuffer fileContent = new StringBuffer();
    		String line;
    		File currentFile = Eclatement.createSplittedFile(fileName, files
    				.size());
    		while ((line = reader.readLine()) != null) {
    			fileContent.append(line+"\n");
    			if (line.equals("P*")) {
    				Eclatement.writeFile(currentFile, fileContent.toString());
    				//System.out.println(currentFile);
    				files.add(currentFile);
    				fileContent = new StringBuffer();
    			currentFile = Eclatement.createSplittedFile(fileName, files
    						.size());
    			}
    		}
    		Eclatement.writeFile(currentFile, fileContent.toString());
     
    		files.add(currentFile);
     
    		splittedFiles = new File[files.size()];
    		int c=0;
    		for (int i = 0; i < files.size(); i++) {
    			setFile(files.get(i));
    			splittedFiles[c] = files.get(c);
    			c++;
    		}
    		return splittedFiles;
    	}
     
    	/**
             * @return the file
             */
    	public static File getFile() {
    		return file;
    	}
     
    	/**
             * @param file the file to set
             */
    	public static void setFile(File file) {
    		Eclatement.file = file;
    	}
     
    	private static void handleToDir(String toDir) {
    		destDir = new File(toDir);
    		if (destDir.exists())
    			destDir.delete();
    		destDir.mkdir();
    	}
     
    	private static File createSplittedFile(String fileName, int index) {
     
       File file=new File(destDir, fileName); // pas terrible, cette variable destDir statique !!!
       String name = file.getName(); 
       int pos = name.lastIndexOf("."); // détection de l'extension
       if( pos<0 ) {
          // pas d'extension
          name += "." + index;
       }
       else {
          name = name.substring(0,pos)+"."+index+name.substring(pos);
       }
       return new File(file.getParentFile(), name);
    	}
     
    	private static void writeFile(File destFile, String content)
    			throws IOException {
    		BufferedWriter writer = new BufferedWriter(new FileWriter(destFile));
    		writer.write(content);
    		//System.out.println(content);
    		writer.flush();
    		writer.close();
    		writer = null;
    	}
     
    	public static void main(String[] args) {
    		try {
    			// 1048576 = 1Mo
    			System.out.println(Eclatement.splitFile("C:/Users/user/Desktop/FICHIER.HPR",
    					"C:/Users/user/Desktop/cible").length
    					+ " files generated");
     
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }

    Ci-joint un extrait du fichier à découper :

    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
    P|1|000000067145|6285548838|1226730|nom~prénon|NOM|20000904|||adresse||0tel|npr~Docteur Nom Prénom~L
    FAC|1|1226730|6285548838|201610112130|450000047~npr~Docteur 	Nom Prénom|adeli~qui~qui
    ACT|1|B|65|1|1|B65||451016232~00015~DC LABO|5201|HRE
    ACT|2|B|5|1|1|B5||451016232~00015~DC LABO|9106|HR
    ACT|3|B|16|1|1|B16||451016232~00015~DC LABO|9005|HR
    P|2|000000067145|6285548838|1226730|nom~prénon|NOM|20000904|||adresse||0tel|npr~Docteur Nom Prénom~L
    FAC|1|1226730|6285548838|201610112130|450000047~npr~Docteur 	Nom Prénom|adeli~qui~qui
    ACT|1|B|65|1|1|B65||451016232~00015~DC LABO|5201|HRE
    P|3|000000067145|6285548838|1226730|nom~prénon|NOM|20000904|||adresse||0tel|npr~Docteur Nom Prénom~L
    FAC|1|1226730|6285548838|201610112130|450000047~npr~Docteur 	Nom Prénom|adeli~qui~qui
    ACT|1|B|65|1|1|B65||451016232~00015~DC LABO|5201|HRE
    ACT|2|B|5|1|1|B5||451016232~00015~DC LABO|9106|HR
    ACT|3|B|16|1|1|B16||451016232~00015~DC LABO|9005|HR
    ACT|4|B|16|1|1|B16||451016232~00015~DC LABO|1205|HR
    ACT|5|B|16|1|1|B16||451016232~00015~DC LABO|3000|HR
    ACT|6|B|16|1|1|B16||451016232~00015~DC LABO|4000|HR
    ....
    L'idée est de sortir un fichier pour chaque P|X| avec une seule qui réunit les lignes en dessous des P actuels.

    Je vous remercie d'avance,

  2. #2
    Membre émérite
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Par défaut
    Une version corrigée et commentée de splitFile :

    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
    public static File[] splitFile(String filePath, String toDir)
        throws IOException {
        handleToDir(toDir);
        List<File> files = new ArrayList<File>();
        reader = new BufferedReader(new FileReader(filePath));
        String fileName = new File(filePath).getName();
        StringBuffer fileContent = new StringBuffer(); // un StringBuilder serait mieux
     
        reader.lines().forEach(l -> fileContent.append(l).append(System.lineSeparator())); // on lit toutes les lignes et on les concatène, avec la méthode #lines, apparue avec java 8
        /*Si on doit rester avec java 7 ou inférieur :
        String line;
        while ((line = reader.readLine()) != null) {
          fileContent.append(line);
        }*/
        String[] parts = fileContent.toString().split("P\\|"); // on découpe à chaque fois qu'on trouve "P|"
        for(int i = 1; i < parts.length;i++){ //on ignore la string à l'index 0, qui est vide (la partie situé avant le premier "P|")
          String part = "P|"+parts[i]; //on rajoute le "P|" enlevé lors du split
          File currentFile = Eclatement.createSplittedFile(fileName,i-1); //on utilise l'index -1 (pour partir de zéro) pour créer le nombre exact de fichiers
          Eclatement.writeFile(currentFile,part);
          files.add(currentFile);
        }
        return files.toArray(new File[files.size()]); // on utilise toArray, tout simplement...
      }
    Petite remarque a passage, utilise plutôt System.lineSeparator() pour les saut de ligne, c'est portable entre les différent OS. Pareil pour le dossier de l'utilisateur, utilise plutôt System.getProperty("user.home"), qui retournera le dossier de l'utilisateur quel que soit le système.
    Autre chose, le fait de tout avoir en static n'est pas forcément génial...

    N'hésite pas si tu as des question.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Février 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Février 2017
    Messages : 4
    Par défaut
    Bonjour,

    Je te remercie, je prends note de tes conseils, je vais optimiser le programme d'après ce que tu m'as dit. Après pour le dossier user, le script va tourner sur un serveur avec des répertoires définis donc je pense que je peux laisser en dur, la je teste seulement sur mon poste.

    Merci encore,

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    On peut faire ça sans split, concaténation, etc (et accèssoirement, en consommant moins de mémoire).

    Un truc comme ça (il faudrait un peu améliorer, je n'aime pas trop le "continue", mais si c'est pour du one shot, ça fera l'affaire) :
    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
     
    String input = "c:/toto/input.txt";
    String output = "c:/toto/output_%d.txt";
     
    int index=1;
    try(BufferedReader reader = Files.newBufferedReader(Paths.get(input),StandardCharsets.UTF_8)) { // adapter le charset...
     
        String line=null;
        do {
            if ( line!=null && line.startsWith("P|") ) { 
                try(BufferedWriter writer = Files.newBufferedWriter(Paths.get(String.format(output,index++)),StandardCharsets.UTF_8)) {
                    do {
    		    writer.write(line);
    		    line = reader.readLine();
    	        } while( line != null && !line.startsWith("P|") );
    	        continue;
    	    }
    	}
    	line = reader.readLine();
        } while(line!=null);
     
    }
    [EDIT]Voilà, encore plus simple :
    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
    int index=1;
    		try(BufferedReader reader = Files.newBufferedReader(Paths.get(input),StandardCharsets.UTF_8)) {
     
    			for(String line = reader.readLine(); line!=null; ) {
    				if ( line.startsWith("P|") ) {
    					try(BufferedWriter writer = Files.newBufferedWriter(Paths.get(String.format(output,index++)),StandardCharsets.UTF_8)) {
    						writer.write(line); 
    						for(line = reader.readLine(); line!=null; ) {
    							if ( line.startsWith("P|") ) break;
    							writer.write(line);
    						}
    					}
    				}
    			}
     
    		}
    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.

  5. #5
    Membre émérite
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    On peut faire ça sans split, concaténation, etc (et accèssoirement, en consommant moins de mémoire).
    Si l'extrait des données est représentatif... si on a des "P|" qui ne sont pas en début de ligne, on ne peut pas se passer du split je crois? (c'est pour ce cas que je n'ai pas utilisé le startWith...)

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Certes. J'ai présupposé que le format était respecté. Tout comme mon prog ne reprend pas les lignes qui seraient devant le premier P| (j'ai supposé qu'on avait bien des séquences, P suivi de non P, alternées). C'est toujours la même problématique : est-ce une moulinette à utiliser une fois pour convertir un fichier inadapté (dont le format est connu et immuable, et éventuellement corrigeable à la main au cas pour élimininer les cas particuliers), ou pour traiter en masse une conversion qui va être appliquée à des milliers d'entrées potentiellement mal formées. Dans ton programme, par exemple, s'il y a un libellé (d'une colonne qui n'est pas la dernière) qui se termine par P, tu vas couper une ligne en deux (parce que P| sera détecté à tord).

    En tout cas, on peut modifier mon prog pour traiter le cas du P en plein milieu, ça introduirait 2 indexof et subtring (pas de split, pas de concaténation).
    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
    int index=1;
    		try(BufferedReader reader = Files.newBufferedReader(Paths.get(input),StandardCharsets.UTF_8)) {
     
    			for(String line = reader.readLine(); line!=null; ) {
    				int i=line.indexOf("P|");
    				if (i>0) {
    					line = line.substring(i);
    				}
    				if ( i>=0 ) {
    					try(BufferedWriter writer = Files.newBufferedWriter(Paths.get(String.format(output,index++)),StandardCharsets.UTF_8)) {
    						writer.write(line); 
    						while( (line=reader.readLine())!=null ) {
    							int pos=line.indexOf("P|");
    							if (pos>0) {
    								writer.write(line.substring(0,pos));
    								break;
    							}
    							else if ( pos==0 ) {
    								break;
    							}
    							else {
    								writer.write(line);
    							}
    						}
    					}
    				}
    			}
     
    		}
    Un peu plus complexe s'il faut traiter le cas du P en fin de libellé (il faudrait un Pattern/Matcher à la place de indexof/substring ).
    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.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. modifier fichier texte en java
    Par billouth dans le forum Langage
    Réponses: 5
    Dernier message: 06/08/2009, 17h52
  2. Question sur lecture d'un fichier text en Java
    Par ovcrash dans le forum Entrée/Sortie
    Réponses: 13
    Dernier message: 27/11/2007, 17h14
  3. Transfert d'un fichier texte avec java
    Par mokhtarmaroc dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 25/08/2007, 10h58
  4. Probléme d'ecriture dans un fichier texte en java
    Par oldscrout dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 19/01/2007, 19h10
  5. Comment ouvrir un fichier text sous Java ?
    Par mpascolo dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 11/10/2006, 14h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo