web-dev-qa-db-fra.com

Chargement de fichier par getClass (). GetResource ()

J'ai suivi la méthode de chargement du fichier de ressources en utilisant getClass.getResource(path). L'extrait de code est ici:

String url = "Test.properties";

System.out.println("Before printing paths..");
System.out.println("Path2: "+ getClass().getResource(url).getPath());

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI()));
i_propConfig.load(inputStream);
inputStream.close();

Je l'ai configuré dans Eclipse avec la hiérarchie (sous le fichier source se trouve un dossier appelé SwingDemo. Dans SwingDemo, il existe mon Java ainsi que le fichier de ressources) ... ...

  1. src
    • SwingDemo
      1. CustomDialog.Java
      2. Test.properties

Lorsque je lance ceci sur Eclipse, tout se passe bien. Mais dès que je tente d'exécuter les applications à partir de cmd line, une exception de pointeur null se produit.

La hiérarchie de déploiement en ligne de commande est la suivante:

Dossier: D:\Work\Java Progrms\SwingDemo

Hiérarchie:

  1. SwingDemo
    • CustomDialog.Java
    • Test.properties

Tout d'abord, j'ai compilé ce fichier dans le dossier SwingDemo à partir de la ligne de commande (javac CustomDialog.Java). Ensuite, je retourne à l'étape Java Programmes (comme je l'ai mentionné le paquet dans la classe .Java) et j'exécute les applications à l'aide du célèbre

Java SwingDemo.CustomDialog

J'avais l'habitude de suivre des étapes similaires lorsque j'utilisais précédemment le nouveau FileInputStream ("chemin"). Après avoir fait cela, je reçois une exception de pointeur nulle ..

Je pense que getClass().getResource(url) ne peut pas charger un fichier depuis un répertoire spécifique. C'est pourquoi j'ai placé la ressource dans le même répertoire que celui de mon fichier Java. Il fonctionnait bien sous Eclipse. Mais pourquoi cela donne une erreur lorsque je suis exécuté à partir de la ligne de commande.

42
AnjanN

getClass().getResource() utilise le chargeur de classes pour charger la ressource. Cela signifie que la ressource doit être dans le classpath pour être chargée.

Lorsque vous le faites avec Eclipse, tout ce que vous mettez dans le dossier source est "compilé" par Eclipse:

  • Les fichiers .Java sont compilés en fichiers .class qui vont dans le répertoire bin (par défaut)
  • les autres fichiers sont copiés dans le répertoire bin (en respectant les recherches de paquet/dossier)

Lors du lancement du programme avec Eclipse, le répertoire bin est donc dans le chemin d'accès aux classes et, puisqu'il contient le fichier Test.properties, ce fichier peut être chargé par le chargeur de classes à l'aide de getResource() ou getResourceAsStream(). .

Si cela ne fonctionne pas à partir de la ligne de commande, c'est parce que le fichier n'est pas dans le chemin d'accès aux classes.

Notez que vous ne devriez pas faire

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI()));

charger une ressource. Parce que cela ne peut fonctionner que si le fichier est chargé à partir du système de fichiers. Si vous compressez votre application dans un fichier jar ou si vous chargez les classes sur un réseau, cela ne fonctionnera pas. Pour obtenir un InputStream, utilisez simplement

getClass().getResourceAsStream("Test.properties")

Et enfin, comme l'indique la documentation,

Foo.class.getResourceAsStream("Test.properties")

chargera un fichier Test.properties situé dans le même package que la classe Foo.

Foo.class.getResourceAsStream("/com/foo/bar/Test.properties")

chargera un fichier Test.properties situé dans le paquet com.foo.bar.

72
JB Nizet

Le meilleur moyen d'accéder aux fichiers depuis le dossier de ressources à l'intérieur d'un fichier jar consiste à utiliser InputStream via getResourceAsStream. Si vous avez toujours besoin d'une ressource en tant qu'instance de fichier, vous pouvez la copier en tant que flux dans un fichier temporaire (le fichier temporaire sera supprimé à la fermeture de la machine virtuelle Java):

public static File getResourceAsFile(String resourcePath) {
    try {
        InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
        if (in == null) {
            return null;
        }

        File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
        tempFile.deleteOnExit();

        try (FileOutputStream out = new FileOutputStream(tempFile)) {
            //copy stream
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }
        return tempFile;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
16
Lukas Masuch