J'essaie de lire un fichier texte défini dans la variable système CLASSPATH. Pas une variable utilisateur.
J'essaie d'obtenir un flux d'entrée dans le fichier comme ci-dessous:
Placez le répertoire du fichier (D:\myDir
) dans CLASSPATH et essayez ci-dessous:
InputStream in = this.getClass().getClassLoader().getResourceAsStream("SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("//SomeTextFile.txt");
Placez le chemin complet du fichier (D:\myDir\SomeTextFile.txt
) dans CLASSPATH et essayez la même chose ci-dessus 3 lignes de code.
Mais malheureusement, AUCUN d’entre eux ne fonctionne et j’enregistre toujours null
dans mon InputStream in
.
Avec le répertoire sur le chemin de classe, à partir d'une classe chargée par le même chargeur de classes, vous devriez pouvoir utiliser l'un des éléments suivants:
// From ClassLoader, all paths are "absolute" already - there's no context
// from which they could be relative. Therefore you don't need a leading slash.
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt");
// From Class, the path is relative to the package of the class unless
// you include a leading slash, so if you don't want to use the current
// package, include a slash like this:
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
Si cela ne fonctionne pas, cela suggère que quelque chose ne va pas.
Ainsi, par exemple, prenons ce code:
package dummy;
import Java.io.*;
public class Test
{
public static void main(String[] args)
{
InputStream stream = Test.class.getResourceAsStream("/SomeTextFile.txt");
System.out.println(stream != null);
stream = Test.class.getClassLoader().getResourceAsStream("SomeTextFile.txt");
System.out.println(stream != null);
}
}
Et cette structure de répertoire:
code
dummy
Test.class
txt
SomeTextFile.txt
Et ensuite (en utilisant le séparateur de chemin Unix comme je suis sur une machine Linux):
Java -classpath code:txt dummy.Test
Résultats:
true
true
Lorsque vous utilisez le cadre Spring (sous forme de collection d'utilitaires ou de conteneur , vous n'avez pas besoin d'utiliser cette dernière fonctionnalité). vous pouvez facilement utiliser l'abstraction Resource.
Resource resource = new ClassPathResource("com/example/Foo.class");
Via l’interface Resource, vous pouvez accéder à la ressource en tant que InputStream, URL, URI ou - Fichier. Changer le type de ressource pour, par exemple, une ressource de système de fichiers consiste simplement à changer l'instance.
Voici comment j'ai lu toutes les lignes d'un fichier texte sur mon chemin de classe, en utilisant Java 7 NIO:
...
import Java.nio.charset.Charset;
import Java.nio.file.Files;
import Java.nio.file.Paths;
...
Files.readAllLines(
Paths.get(this.getClass().getResource("res.txt").toURI()), Charset.defaultCharset());
NB ceci est un exemple de la façon dont cela peut être fait. Vous devrez apporter des améliorations si nécessaire. Cet exemple ne fonctionnera que si le fichier est réellement présent sur votre chemin d'accès aux classes. Sinon, une exception NullPointerException sera levée lorsque getResource () renverra null et que .toURI () y sera invoqué.
De plus, depuis Java 7, un moyen pratique de spécifier des jeux de caractères consiste à utiliser les constantes définies dans Java.nio.charset.StandardCharsets
(elles sont, selon leur javadocs , "garantis être disponible sur chaque implémentation de la plate-forme Java. ").
Par conséquent, si vous savez que le codage du fichier est UTF-8, spécifiez explicitement le jeu de caractères StandardCharsets.UTF_8
S'il vous plaît essayez
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
Vos essais n'ont pas fonctionné car seul le chargeur de classes pour votre classes est capable de se charger depuis le classpath. Vous avez utilisé le chargeur de classes pour le système Java lui-même.
Pour lire le contenu du fichier, j'aime bien utiliser Commons IO + Spring Core. En supposant que Java 8:
try (InputStream stream = new ClassPathResource("package/resource").getInputStream()) {
IOUtils.toString(stream);
}
Alternativement:
InputStream stream = null;
try {
stream = new ClassPathResource("/log4j.xml").getInputStream();
IOUtils.toString(stream);
} finally {
IOUtils.closeQuietly(stream);
}
Pour obtenir le chemin absolu de la classe, essayez ceci:
String url = this.getClass().getResource("").getPath();
D'une certaine manière, la meilleure réponse ne fonctionne pas pour moi. J'ai besoin d'utiliser un code légèrement différent à la place.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("SomeTextFile.txt");
J'espère que cela aidera ceux qui rencontrent le même problème.
Si vous utilisez la goyave:
import com.google.common.io.Resources;
nous pouvons obtenir l'URL de CLASSPATH:
URL resource = Resources.getResource("test.txt");
String file = resource.getFile(); // get file path
ou InputStream:
InputStream is = Resources.getResource("test.txt").openStream();
Pour lire le contenu d'un fichier dans une chaîne à partir de classpath
, vous pouvez utiliser ceci:
_private String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath))
{
return IOUtils.toString(inputStream);
}
}
_
Remarque:IOUtils
fait partie de Commons IO
.
Appelez ça comme ça:
_String fileContents = resourceToString("ImOnTheClasspath.txt");
_
Vous dites "J'essaie de lire un fichier texte défini dans la variable système CLASSPATH". Je suppose que c'est sous Windows et que vous utilisez cette boîte de dialogue moche pour éditer les "variables système".
Maintenant, vous exécutez votre programme Java dans la console. Et cela ne fonctionne pas: la console reçoit une copie des valeurs des variables système ne fois quand il s’agit de démarré. Cela signifie que tout changement dans le dialogue après n'a aucun effet.
Il y a ces solutions:
Démarrer une nouvelle console après chaque changement
Utilisez set CLASSPATH=...
dans la console pour définir la copie de la variable dans la console. Lorsque votre code fonctionnera, collez la dernière valeur dans le dialogue de variable.
Mettez l'appel à Java dans le fichier .BAT
et double-cliquez dessus. Cela créera une nouvelle console à chaque fois (copiant ainsi la valeur actuelle de la variable système).
ATTENTION: Si vous avez également une variable utilisateur CLASSPATH
, votre variable système sera alors occultée. C’est pourquoi il est généralement préférable de placer l’appel de votre programme Java dans un fichier .BAT
et de définir le chemin d'accès aux classes (avec set CLASSPATH=
) plutôt que de s'appuyer sur un système global. ou variable utilisateur.
Cela garantit également que vous pouvez avoir plusieurs programmes Java sur votre ordinateur, car ils doivent obligatoirement avoir différents chemins de classes.
Ma réponse n'est pas exactement ce qui est demandé dans la question. Au lieu de cela, je donne une solution exactement avec quelle facilité nous pouvons lire un fichier dans une application Java à partir de notre chemin de classe de projet.
Par exemple, supposons qu'un nom de fichier de configuration example.xml se trouve dans un chemin comme ci-dessous: -
com.myproject.config.dev
et notre fichier de classe exécutable Java se trouve dans le chemin ci-dessous: -
com.myproject.server.main
maintenant, vérifiez simplement dans le chemin ci-dessus qui est le répertoire/dossier commun le plus proche d'où vous pouvez accéder à la fois dev et ) principal répertoire/dossier (com.myproject.server.main - où la classe exécutable Java de notre application est existante) - Nous pouvons voir qu’elle se trouve myproject dossier/répertoire qui est le répertoire/dossier commun le plus proche à partir duquel nous pouvons accéder à notre fichier example.xml. Par conséquent, depuis une classe exécutable Java, elle réside dans le dossier/répertoire principal , nous devons revenir en arrière deux étapes telles que ../../ pour accéder à mon projet . Maintenant, voyez comment on peut lire le fichier: -
package com.myproject.server.main;
class Example {
File xmlFile;
public Example(){
String filePath = this.getClass().getResource("../../config/dev/example.xml").getPath();
this.xmlFile = new File(filePath);
}
public File getXMLFile() {
return this.xmlFile;
}
public static void main(String args[]){
Example ex = new Example();
File xmlFile = ex.getXMLFile();
}
}