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 :

Problème de chemin de fichier selon execution du programme JAVA


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur Développement/Intégration
    Inscrit en
    Mai 2012
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Développement/Intégration
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 32
    Par défaut Problème de chemin de fichier selon execution du programme JAVA
    Bonjour,

    J'ai un fichier CreationTable_SuiviCumul.sql qui se trouve dans mon projet "TraitementReferentielFlux" dans le répertoire : "requetesSQL" :


    Nom : 2021-03-25-CheminFichier-01.png
Affichages : 1180
Taille : 79,2 Ko

    J'ai crée l'opération suivante qui permet de tenir compte de la forme des chemins de fichiers selon l'environnement dans lequel le programme est executé :

    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
     
       public String gestionCheminFichier(String e_cheminRelatif, String e_nomFichier) {
     
            // Déclaration des variables locales
            String s_nomLongLocalFichier = null;
            String l_cheminJREJava = null;
            String l_separateurDeFichier = null;
     
            String[] l_tableauRepertoiresUnitaires = null;
     
            ClassLoader l_classloader = null;
            URL l_url = null;
     
            l_cheminJREJava = System.getProperty("java.home");
     
            System.out.println("Le chemin de la JRE java est : " + l_cheminJREJava);
     
            l_separateurDeFichier = System.getProperty("file.separator");
     
            l_tableauRepertoiresUnitaires = l_cheminJREJava.split(Pattern.quote(l_separateurDeFichier));
     
            // Pour éviter des problèmes de différence d'arborescence entre l'excution sous Eclipse
            // et l'execution via un script dos ou shell, il faut utiliser les 2 lignes d'instructions suivantes
            l_classloader = Thread.currentThread().getContextClassLoader();
     
            l_url = l_classloader.getResource(e_cheminRelatif + e_nomFichier);
     
            System.out.println("L'URL est : " + l_url);
     
            // Dans Eclipse le chemin de la JRE est :
            // C:\Program Files\Eclipse_DEV\Jdks\jdk1.8\jre
            // Sous DOS le chemin est : C:\Program Files (x86)\Java\jre1.8.0_91
            // On recupère le 3éme membre du tableau pour voir s'il est égale à Eclipse_DEV (environnement Eclipse)
            // ou non (environnement DOS)
            if ("Eclipse_DEV".equals(l_tableauRepertoiresUnitaires[2])) {
     
                // Le getFile() de URL imprime en premier caractère un slash (/) que nous ne souhaitons pas d'ou le substring
                s_nomLongLocalFichier = l_url.getFile().substring(1);
     
            } else {
     
                // Le getFile() de URL imprime en premier caractère un slash (/) que nous ne souhaitons pas d'ou le substring
                // Exemple : /file:/C:/User/E524761/eclipse/workspace/TraitementReferentielFlux/bin/requetesSQL/CreationTable_SuiviEntreeCumul.sql
                // Il faut supprimer la chaine de caractère suivante : /file:/
                s_nomLongLocalFichier = l_url.getFile().substring(6);
            }
     
            System.out.println("Le nom long du fichier est : " + s_nomLongLocalFichier);
     
            return s_nomLongLocalFichier;
        }

    Quand je l'execute sous Eclipse, je n'ai pas de problème. Le fichier CreationTable_SuiviCumul.sql est bien trouvé et pris en compte.

    Par contre lorsque j'execute le programme sous DOS, j'ai l'erreur suivante :

    ...
    Caused by: java.io.FileNotFoundException: C:\TEMP\referentiel\bin\TraitementReferentielFlux.jar!\requetesSQL\CreationTable_SuiviCumul.sql (Le chemin d?accès spécifié est introuvable)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    ...
    Est ce que quelqu'un aurait une idée.

    Par avance merci.

    Bien à vous.

  2. #2
    Membre Expert
    Avatar de Mickael_Istria
    Homme Profil pro
    Développeur Expert Eclipse IDE/RCP, pour Red Hat
    Inscrit en
    Juillet 2008
    Messages
    1 479
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Expert Eclipse IDE/RCP, pour Red Hat
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 479
    Par défaut
    Ca ressemble a un probleme d'export de l'application. Tu as regarde dans ton jar si le fichier .sql est bien present? Verifie ton etape d'export vers jar pour etre sur que ces fichiers soient inclus.

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Hello,

    en fait non, le problème c'est que la classe File ne représente que des fichiers présents sur le système de fichier de l'OS. Pas, donc, des fichiers qui seraient enfermés dans une archive .jar. On ne peut pas utiliser la classe File pour accéder à ceux-là.

    La classe File marche très bien tant que le programme est éclaté en fichiers épars dans l'EDI, mais ne peut pas marcher une fois qu'on les a rassemblés dans une archive.

    La classe File n'est donc pas ce qu'il faut utiliser.

    A la place, il vaut mieux utiliser quelque chose comme getResourceAsStream(), qui fournit un InputStream qui lit une ressource présente dans le classpath (que ce classpath utilise des répertoires, des .jar, ou quoi que ce soit).

    Ça ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try(InputStream is = UneClassQuelconque.class.getResourceAsStream("/requetesSQL/CreationTable_SuiviCumul.sql")) {
     
      // et là il n'y a plus qu'à lire le contenu de is
     
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur Développement/Intégration
    Inscrit en
    Mai 2012
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Développement/Intégration
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2012
    Messages : 32
    Par défaut Comportement différent du jar entre DOS et l'IDE Eclipse
    Bonjour,

    Merci Thelvin, oui effectivement c'est ça.

    Lorsque j'execute mon application TraitementReferentielFlux sous Eclipse, le répertoire courant dans mon cas sera :

    C:\User\E524761\eclipse\workspace\TraitementReferentielFlux\bin

    Alors que dans le cas où j'execute sous DOS sous forme de jar, le répertoire courant sera :

    C:\TEMP\referentiel\bin\TraitementReferentielFlux.jar


    Dans mon cas, je souhaitais récupérer le nom long du fichier (chemin + nom du fichier) pour envoyer le fichier via Jsch (protocole sftp) sur un serveur UNIX.
    Donc, de la façon dont est fait mon programme et pour éviter de remanier trop de code, je souhaitais absolument utiliser l'opération getResource plutôt que getResourceAsStream.

    L'idée, dans le cas de l'execution sous DOS, a donc été d'extraire de mon jar le répertoire qui m'interessais :

    Une partie de ce code a été récupéré sur un autre forum :

    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
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
     
        // l'idée ici de cette opération est d'extraire uniquement du fichier jar le répertoire suivant :
        // requetesSQL/ et scriptsShell/
        public void dezipperUnePartieDuFichierJar(String e_nomFichierJar, String[] e_RepertoiresAExtraire) throws FileNotFoundException, IOException {
     
            // Déclaration des varibales locales
            FileInputStream l_fileInputStream = null;
            BufferedInputStream l_bufferedInputStream = null;
            ZipInputStream l_zipInputStream = null;
            ZipEntry l_zipEntry = null;
            File l_fichier = null;
            OutputStream l_outputStream = null;
            File l_fichierJar = null;
            File l_repertoire = null;
     
            String l_nomRepertoire = null;
            String l_extension = null;
     
            int l_nombreDOctetesLus = 0;
            int l_positionPoint = 0;
            char l_point = '.';
            boolean l_drapeauSuppressionRepertoire = false;
            boolean l_drapeauCreationRepertoire = false;
            boolean l_drapeauSuiteTraitement = false;
     
            try {
     
                l_positionPoint = e_nomFichierJar.indexOf(l_point);
     
                l_nomRepertoire = e_nomFichierJar.substring(0, l_positionPoint);
     
                System.out.println("Le nom long du fichier jar est : " + e_nomFichierJar);
                System.out.println("Le nom du répertoire est : " + l_nomRepertoire);
     
                l_fichierJar = new File(e_nomFichierJar);
                l_repertoire = new File(l_nomRepertoire);
     
                // Si le répertoire existe le supprimer
                if (l_repertoire.exists()) {
                    l_drapeauSuppressionRepertoire = suppressionDUnRepertoire(l_repertoire);
     
                    if (l_drapeauSuppressionRepertoire == true) {
                        System.out.println("le répertoire " + l_nomRepertoire + " et tout son contenu a bien été supprimer");
                    } else {
                        System.out.println("le répertoire " + l_nomRepertoire + " n'a pas pu être supprimé");
                    }
                }
     
                // Petit temps d'attente, pour laisser le temps au processus de vraiment supprimer le répertoire
                // Sinon le processus n'arrive pas a recréer le répertoire
                Thread.sleep(3000);
     
                // Puis le recréer
                l_drapeauCreationRepertoire = l_repertoire.mkdir();
     
                if (l_drapeauCreationRepertoire == true) {
                    System.out.println("le répertoire " + l_nomRepertoire + " a été recrée à vide");
                } else {
                    System.out.println("le répertoire " + l_nomRepertoire + " n'a pas pu être recrée à vide");
                }
     
                // création de la ZipInputStream qui va servir à lire les données du fichier jar
                l_fileInputStream = new FileInputStream(l_fichierJar.getCanonicalFile());
                l_bufferedInputStream = new BufferedInputStream(l_fileInputStream);
                l_zipInputStream = new ZipInputStream(l_bufferedInputStream);
     
                // extractions des entrées du fichiers zip (c'est à dire le contenu du fichier jar)
                while ((l_zipEntry = l_zipInputStream.getNextEntry()) != null) {
     
                    // Pour chaque entrée, on crée un fichier
                    // dans le répertoire de sortie "l_repertoire"
                    l_fichier = new File(l_repertoire.getCanonicalPath(), l_zipEntry.getName());
     
                    // System.out.println("Le zip entry est : " + l_zipEntry.getName());
     
                    // Si l'entrée est un répertoire,
                    // on le crée dans le répertoire de sortie
                    // et on passe à l'entrée suivante (continue)
                    if (l_zipEntry.isDirectory()) {
     
                        if (l_zipEntry.getName().equals(e_RepertoiresAExtraire[0]) || l_zipEntry.getName().equals(e_RepertoiresAExtraire[1])) {
                            l_fichier.mkdirs();
                            l_drapeauSuiteTraitement = true;
                        } else {
                            l_drapeauSuiteTraitement = false;
                        }
     
                        // on ne lit pas les instructions suivantes, on passe à l'itération de boucle suivante
                        continue;
                    }
     
                    l_positionPoint = l_zipEntry.getName().indexOf(l_point);
     
                    l_extension = l_zipEntry.getName().substring(l_positionPoint + 1);
     
                    // La condition ici est de crée des fichiers Uniquement s'il font partie du répertoire
                    // requetesSQL/ et scriptsShell/ (condition l_drapeauSuiteTraitement == true)
                    // et le ficier ne doit pas avoir l'extension .class
                    if (l_drapeauSuiteTraitement == true && !"class".equals(l_extension)) {
     
                        // L'entrée est un fichier, on crée une OutputStream
                        // pour écrire le contenu du nouveau fichier
                        l_fichier.getParentFile().mkdirs();
                        l_outputStream = new BufferedOutputStream(new FileOutputStream(l_fichier));
     
                        // On écrit le contenu du nouveau fichier
                        // qu'on lit à partir de la ZipInputStream
                        // au moyen d'un buffer (byte[])
                        try {
                            try {
                                final byte[] l_tableauDeBytes = new byte[8192];
                                l_nombreDOctetesLus = 0;
     
                                while (-1 != (l_nombreDOctetesLus = l_zipInputStream.read(l_tableauDeBytes))) {
                                    l_outputStream.write(l_tableauDeBytes, 0, l_nombreDOctetesLus);
                                }
     
                            } finally {
                                l_outputStream.close();
                            }
     
                        } catch (final IOException ioe) {
                            // en cas d'erreur on efface le fichier
                            l_fichier.delete();
                            throw ioe;
                        }
                    }
                }
     
            } catch (InterruptedException e) {
                e.getStackTrace();
            } finally {
                // fermeture de la ZipInputStream
                l_zipInputStream.close();
            }
        }

    Dans cette opération je supprime au préalable, le répertoire (de façon récursive) que je tente ensuite de récréer (dans l'opération décrite juste au dessus).
    Une partie de ce code a été récupéré sur un autre forum :

    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
     
        // Operation pour supprimer un repertoire et tout ce qu'il contient
        boolean suppressionDUnRepertoire(File e_repertoireASupprimer) {
     
            // Déclaration des varibales locales
            File[] l_tableauDeFichiers = null;
     
            boolean s_drapeauRepertoireSupprime = false;
     
            l_tableauDeFichiers = e_repertoireASupprimer.listFiles();
     
            if (l_tableauDeFichiers != null) {
     
                for (File l_fichierASupprimer : l_tableauDeFichiers) {
                    suppressionDUnRepertoire(l_fichierASupprimer);
                }
            }
     
            // Suppression du repertoire racine
            s_drapeauRepertoireSupprime = e_repertoireASupprimer.delete();
     
            return s_drapeauRepertoireSupprime;
        }

    Et l'opération de la gestion des répertoires selon le mode d'execution :

    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
     
        public String gestionCheminFichier(String e_cheminRelatif, String e_nomFichier) {
     
            // Déclaration des variables locales
            String s_nomLongLocalFichier = null;
            String l_typeDEntite = null;
     
            ClassLoader l_classloader = null;
            URL l_url = null;
            URI l_uri = null;
     
            try {
     
                // l_cheminJREJava = System.getProperty("java.home");
                // l_separateurDeFichier = System.getProperty("file.separator");
     
                // Pour éviter des problèmes de différence d'arborescence entre l'excution sous Eclipse
                // et l'execution via un script dos ou shell, il faut utiliser les 2 lignes d'instructions suivantes
                l_classloader = Thread.currentThread().getContextClassLoader();
     
                System.out.println("le chemin relatif du fichier est : " + e_cheminRelatif + e_nomFichier);
     
                l_url = l_classloader.getResource(e_cheminRelatif + e_nomFichier);
                // l_url = this.getClass().getResource(e_cheminRelatif + e_nomFichier);
                // l_url = Fichiers.class.getResource(e_cheminRelatif + e_nomFichier);
                // l_url = ClassLoader.getSystemResource(e_cheminRelatif + e_nomFichier);
     
                l_uri = l_url.toURI();
     
                System.out.println("L'URL est : " + l_url);
                System.out.println("Le chemin URL est : " + l_url.getPath());
                System.out.println("Le Sheme URI est : " + l_uri.getScheme());
     
                l_typeDEntite = l_uri.getScheme();
     
                // Dans Eclipse le type d'entité (Sheme) est : file
                // sous DOS le type d'entité (Sheme) est jar
                // C:\Program Files\Eclipse_DEV\Jdks\jdk1.8\jre
                if ("file".equals(l_typeDEntite)) {
     
                    // Le getPath() de URL imprime en premier caractère un slash (/) que nous ne souhaitons pas d'ou le substring
                    // Exemple : /C:/User/E524761/eclipse/workspace/TraitementReferentielFlux/bin/requetesSQL/CreationTable_SuiviCumul.sql
                    s_nomLongLocalFichier = l_url.getPath().substring(1);
                } else {
     
                    // Le getPath() de URL imprime, au début, la chaine de caractère suivante : file:/ que nous ne souhaitons pas d'ou le substring
                    // Exemple : file:/C:/TEMP/referentiel/bin/TraitementReferentielFlux.jar!/requetesSQL/CreationTable_SuiviCumul.sq
                    // Il faut supprimer la chaine de caractère suivante : file:/
                    s_nomLongLocalFichier = l_url.getPath().substring(6);
     
                    // De plus je souhaite supprimer la chaine de caractère suivante .jar!, ce qui peremttra au process d'aller dans le répertoire
                    // suivant :
                    // C:/TEMP/referentiel/bin/TraitementReferentielFlux.jar!/requetesSQL/CreationTable_SuiviCumul.sql devienne :
                    // C:/TEMP/referentiel/bin/TraitementReferentielFlux/requetesSQL/CreationTable_SuiviCumul.sql
                    s_nomLongLocalFichier = s_nomLongLocalFichier.replace(".jar!", "");
     
                }
     
                System.out.println("Le nom long du fichier est : " + s_nomLongLocalFichier + "\n");
     
            } catch (URISyntaxException e) {
                e.getStackTrace();
            }
     
            return s_nomLongLocalFichier;
        }


    Et voici une partie de l'opération qui appelle ce 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
     
    ...
     
                // Pour éviter des problèmes de différence d'arborescence entre l'excution sous Eclipse
                // et l'execution via un script dos ou shell, il faut utiliser les 2 lignes d'instructions suivantes
                l_classLoader = Thread.currentThread().getContextClassLoader();
     
                // Pour des raisons inconnus sous DOS l_classLoader.getResource("./") qui aurait été susceptible d'être le répertoire courant
                // n'est pas pris en compte, il à falllut donc ruser er rajouter le chemin requetesSQL/ pour ensuite le suppprimé
                // pour se retrouver sur dans le chemin courant ...
                l_url = l_classLoader.getResource(l_nomDuRepertoireSQLDansJar);
                l_uri = l_url.toURI();
                l_typeDEntite = l_uri.getScheme();
                l_cheminCourant = l_url.getPath();
     
                // Le traitement d'extraction de 2 repertoires du fichier *.jar ne doit se faire QUE dans le cas
                // d'execution sous DOS, c'est à daire dans le cas ou le type d'entité (Sheme) est égale à jar
                if ("jar".equals(l_typeDEntite)) {
     
                    l_repertoiresAExtraire[0] = l_nomDuRepertoireSQLDansJar;
                    l_repertoiresAExtraire[1] = l_nomDuRepertoireSHDansJar;
     
                    // Suppression du début de chaine de caratère qui ressemble à : file:/
                    l_cheminCourant = l_cheminCourant.substring(6);
     
                    // Suppression de la fin de chaine : !/requetesSQL/ qui ne nous interesse pas
                    l_positionPointExclamation = l_cheminCourant.indexOf(l_pointExclamation);
                    l_nomFichierJar = l_cheminCourant.substring(0, l_positionPointExclamation);
     
                    // Extractions UNIQUEMENT de 2 répertoires du fichier jar
                    l_fichiers.dezipperUnePartieDuFichierJar(l_nomFichierJar, l_repertoiresAExtraire);
     
                }
     
                l_nomLongLocalFichierSHRecuperationSuiviCumul = l_fichiers.gestionCheminFichier(l_nomDuRepertoireSHDansJar,
                        l_nomScriptSHRecuperationFichiersSuivi);
                l_nomLongLocalFichierSQLSuiviCumul = l_fichiers.gestionCheminFichier(l_nomDuRepertoireSQLDansJar, l_nomFichierSQLSuiviCumul);
                l_nomLongLocalFichierSHSuiviCumul = l_fichiers.gestionCheminFichier(l_nomDuRepertoireSHDansJar, l_nomScriptSHSuiviCumul);
     
    ...
    Je ferme la discussion.

    Bien à vous.

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

Discussions similaires

  1. Problème de chemin de fichier (include)
    Par sami_c dans le forum Apache
    Réponses: 1
    Dernier message: 15/09/2008, 21h11
  2. Problème de chemin de fichier avec des espaces
    Par Akronyme dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 11/12/2006, 17h12
  3. Problème de chemin de fichier complexe
    Par Gianluca dans le forum Requêtes
    Réponses: 2
    Dernier message: 22/08/2006, 11h06
  4. [CKEditor] problème de chemin de fichier avec fck editor
    Par Benjiijneb dans le forum Bibliothèques & Frameworks
    Réponses: 7
    Dernier message: 31/01/2006, 09h05
  5. [MFC]Problème de chemin de fichier
    Par benahpets dans le forum MFC
    Réponses: 3
    Dernier message: 06/09/2005, 13h07

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