web-dev-qa-db-fra.com

ressource ouverte avec chemin relatif en java

Dans mon application Java, j'ai besoin de fichiers et de répertoires.

Voici la structure du programme:

./main.Java
./package1/guiclass.Java
./package1/resources/resourcesloader.Java
./package1/resources/repository/modules/   -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks    -> this is the file I need to get

guiclass charge la classe resourcesloader qui chargera mes ressources (répertoire et fichier).

Quant au dossier, j'ai essayé

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()

afin d'obtenir le vrai chemin, mais cette façon ne fonctionne pas.

Je ne sais pas comment faire le répertoire.

73
Giancarlo

Indiquez le chemin relatif au chargeur de classe, pas à la classe à partir de laquelle vous obtenez le chargeur. Par exemple:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
39
jonathan.cone

J'ai eu des problèmes avec l'utilisation de la méthode getClass().getResource("filename.txt") . Lors de la lecture des instructions relatives à la documentation Java, si votre ressource ne se trouve pas dans le même package que la classe à partir de laquelle vous essayez d'accéder à la ressource, vous devez lui attribuer un chemin relatif commençant par '/'. La stratégie recommandée consiste à placer vos fichiers de ressources dans un dossier "ressources" dans le répertoire racine. Donc, par exemple si vous avez la structure:

src/main/com/mycompany/myapp

alors vous pouvez ajouter un dossier de ressources comme recommandé par maven dans:

src/main/resources

en outre, vous pouvez ajouter des sous-dossiers dans le dossier des ressources.

src/main/resources/textfiles

et dites que votre fichier s'appelle myfile.txt donc vous avez 

src/main/resources/textfiles/myfile.txt

Maintenant, voici où le problème du chemin stupide entre en jeu. Supposons que vous avez une classe dans votre com.mycompany.myapp package et que vous souhaitez accéder au fichier myfile.txt à partir de votre dossier de ressources. Certains disent que vous devez donner le:

"/main/resources/textfiles/myfile.txt" path

ou 

"/resources/textfiles/myfile.txt"

les deux sont faux. Après avoir exécuté mvn clean compile, les fichiers et les dossiers sont copiés dans le dossier suivant:

myapp/target/classes 

dossier. Mais le dossier de ressources n'est pas là, seulement les dossiers dans le dossier de ressources. Donc vous avez:

myapp/target/classes/textfiles/myfile.txt

myapp/target/classes/com/mycompany/myapp/*

le chemin correct à donner à la méthode getClass().getResource("") est donc:

"/textfiles/myfile.txt"

c'est ici:

getClass().getResource("/textfiles/myfile.txt")

Cela ne retournera plus nul, mais votre classe ....... J'espère que cela aidera quelqu'un. Pour moi, il est étrange que le dossier "resources" ne soit pas copié également, mais uniquement les sous-dossiers et les fichiers directement dans le dossier "resources". Il me semblerait logique que le dossier "resources" se trouve également sous "myapp/target/classes"

135
Johnny

Dans l’espoir de fournir des informations supplémentaires à ceux qui ne lisent pas cela aussi rapidement que les autres, j'aimerais vous présenter mon scénario, car sa configuration est légèrement différente. Mon projet a été configuré avec la structure de répertoire suivante (utilisant Eclipse):

Projet/
 src/// code source de l'application 
 org /
 mon projet/
 MyClass.Java 
 test/// tests unitaires 
 res/// ressources 
 images/// images PNG pour les icônes 
 my-image.png 
 xml/// Fichiers XSD pour la validation de fichiers XML avec JAXB 
 my-schema.xsd 
 conf/// fichier .conf par défaut pour Log4j 
 log4j.conf 
 bibliothèques lib/// ajoutées au chemin de construction via les paramètres du projet 

J'avais des problèmes pour charger mes ressources à partir du répertoire res. Je voulais que toutes mes ressources soient séparées de mon code source (simplement à des fins de gestion/d'organisation). Donc, ce que je devais faire était d’ajouter le répertoire res au répertoire chemin de construction, puis d’accéder à la ressource via:

static final ClassLoader loader = MyClass.class.getClassLoader();

// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");

REMARQUE: Le / est omis au début de la chaîne de ressource car j'utilise ClassLoader.getResource (String) au lieu de Class.getResource (String) .

30
E-rich

@GianCarlo: Vous pouvez appeler la propriété système user.dir qui vous donnera la racine de votre projet Java, puis ajoutez ce chemin à votre chemin relatif, par exemple:

String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;



// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
8
Vikram

Lorsque vous utilisez 'getResource' sur une classe, un chemin relatif est résolu en fonction du package dans lequel se trouve la classe. Lorsque vous utilisez 'getResource' sur un chargeur de classe, un chemin relatif est résolu en fonction du dossier racine.

Si vous utilisez un chemin absolu, les deux méthodes 'getResource' commenceront au dossier racine.

7
nbeyer

Pour ceux qui utilisent Eclipse + maven. Supposons que vous essayez d'accéder au fichier images/pic.jpg dans src/main/resources. En le faisant de cette façon: 

ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());

est parfaitement correct, mais peut entraîner une exception de pointeur nul. On dirait que Eclipse ne reconnaît pas immédiatement les dossiers de la structure de répertoires maven en tant que dossiers sources. En supprimant le dossier src/main/resources de la liste des dossiers source du projet et en le remettant (projet> propriétés> chemin de construction Java> source> supprimer/ajouter un dossier), j'ai pu résoudre ce problème. 

4
Paul Mira
resourcesloader.class.getClass()

Peut être décomposé en:

Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();

Ce qui signifie que vous essayez de charger la ressource en utilisant une classe d'amorçage.

Au lieu de cela, vous voulez probablement quelque chose comme:

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

Si seulement javac était averti d'appeler des méthodes statiques dans des contextes non statiques ...

2
Tom Hawtin - tackline

Aller avec les deux réponses comme mentionné ci-dessus. Le premier

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

Devrait être une seule et même chose?

1
manocha_ak

Est-ce que le travail suivant?

resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")

Y a-t-il une raison pour laquelle vous ne pouvez pas spécifier le chemin complet, y compris le package?

1
RichH

Utilisez ceci:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
0
Oleg Poltoratskii

Afin d’obtenir un vrai chemin vers le fichier, vous pouvez essayer ceci:

URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;    

Resourceloader est classname ici. "resources/repository/SSL-Key/cert.jks" est le chemin relatif du fichier. Si votre classe guiclass se trouvait dans ./package1/Java avec le reste de la structure de dossiers, vous prendriez "../resources/repository/SSL-Key/cert.jks" comme chemin relatif en raison des règles définissant le chemin relatif.

De cette façon, vous pouvez lire votre fichier avec BufferedReader. N'UTILISEZ PAS LA CHAÎNE pour identifier le chemin du fichier, car si vous avez des espaces ou des caractères d'alphabet non anglais dans votre chemin, vous aurez des problèmes et le fichier ne sera pas trouvé.

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));
0
Nikto

J'ai apporté une petite modification à l'un des doublons de @ jonathan.cone (en ajoutant .getFile()) pour éviter une exception de pointeur nul et pour définir le chemin d'accès au répertoire de données. Voici ce qui a fonctionné pour moi:

String realmID = new Java.util.Scanner(new Java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
0
Alferd Nobel