1 pièce(s) jointe(s)
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" :
Pièce jointe 594270
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:
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 :
Citation:
...
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.
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:
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:
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:
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:
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.