J'essaie d'obtenir un chemin vers une ressource mais je n'ai pas eu de chance.
Cela fonctionne (à la fois dans IDE et avec le fichier JAR), mais de cette manière, je ne peux pas obtenir un chemin d'accès à un fichier, seul le contenu du fichier:
ClassLoader classLoader = getClass().getClassLoader();
PrintInputStream(classLoader.getResourceAsStream("config/netclient.p"));
Si je fais ça:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("config/netclient.p").getFile());
Le résultat est: Java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory)
Est-il possible d'obtenir un chemin d'accès à un fichier de ressources?
C'est délibéré. Le contenu du "fichier" peut ne pas être disponible sous forme de fichier. N'oubliez pas que vous traitez avec des classes et des ressources pouvant faire partie d'un fichier JAR ou d'un autre type de ressource. Le chargeur de classes n'a pas à fournir de descripteur de fichier à la ressource. Par exemple, le fichier jar n'a peut-être pas été développé en fichiers individuels dans le système de fichiers.
Tout ce que vous pouvez faire en obtenant un fichier Java.io.File peut être fait en copiant le flux dans un fichier temporaire et en faisant de même, si un fichier Java.io.File est absolument nécessaire.
Lorsque vous chargez une ressource, assurez-vous de noter la différence entre:
getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
et
getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning
J'imagine que cette confusion est à l'origine de la plupart des problèmes lors du chargement d'une ressource.
De plus, lorsque vous chargez une image, il est plus facile d'utiliser getResourceAsStream()
:
BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));
Lorsque vous devez réellement charger un fichier (non-image) à partir d'une archive JAR, vous pouvez essayer ceci:
File file = null;
String resource = "/com/myorg/foo.xml";
URL res = getClass().getResource(resource);
if (res.getProtocol().equals("jar")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.close();
file.deleteOnExit();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if (file != null && !file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}
La réponse en une ligne est -
String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
En gros, la méthode getResource
donne l'URL. À partir de cette URL, vous pouvez extraire le chemin en appelant toExternalForm()
Références:
J'ai passé un moment à déconner avec ce problème, parce qu'aucune solution que j'ai trouvée ne fonctionnait réellement, assez étrangement! Le répertoire de travail n’est souvent pas le répertoire du fichier JAR, en particulier si un fichier JAR (ou tout autre programme) est exécuté à partir du menu Démarrer de Windows. Voici donc ce que j'ai fait et cela fonctionne pour les fichiers .class exécutés à l'extérieur d'un fichier JAR aussi bien que pour un fichier JAR. (Je ne l'ai testé que sous Windows 7.)
try {
//Attempt to get the path of the actual JAR file, because the working directory is frequently not where the file is.
//Example: file:/D:/all/Java/TitanWaterworks/TitanWaterworks-en.jar!/TitanWaterworks.class
//Another example: /D:/all/Java/TitanWaterworks/TitanWaterworks.class
PROGRAM_DIRECTORY = getClass().getClassLoader().getResource("TitanWaterworks.class").getPath(); // Gets the path of the class or jar.
//Find the last ! and cut it off at that location. If this isn't being run from a jar, there is no !, so it'll cause an exception, which is fine.
try {
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('!'));
} catch (Exception e) { }
//Find the last / and cut it off at that location.
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('/') + 1);
//If it starts with /, cut it off.
if (PROGRAM_DIRECTORY.startsWith("/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(1, PROGRAM_DIRECTORY.length());
//If it starts with file:/, cut that off, too.
if (PROGRAM_DIRECTORY.startsWith("file:/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(6, PROGRAM_DIRECTORY.length());
} catch (Exception e) {
PROGRAM_DIRECTORY = ""; //Current working directory instead.
}
si netclient.p
se trouve dans un fichier JAR, il n'y aura pas de chemin car ce fichier se trouve dans un autre fichier. dans ce cas, le meilleur chemin que vous pouvez avoir est vraiment file:/path/to/jarfile/bot.jar!/config/netclient.p
.
Vous devez comprendre le chemin dans le fichier jar.
Il suffit de s'y référer relatif. Donc, si vous avez un fichier (myfile.txt), situé dans foo.jar dans le répertoire \src\main\resources
(style maven). Vous vous y référeriez comme:
src/main/resources/myfile.txt
Si vous videz votre fichier jar en utilisant jar -tvf myjar.jar
, vous verrez la sortie et le chemin relatif dans le fichier jar, et vous utiliserez FORWARD SLASHES.
Il s'agit du même code d'utilisateur Tombart avec flux et fermeture de flux afin d'éviter la copie incomplète du contenu du fichier temporaire à partir de la ressource jar et d'avoir des noms de fichier temporaires uniques.
File file = null;
String resource = "/view/Trial_main.html" ;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile(new Date().getTime()+"", ".html");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
input.close();
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
Dans mon cas, j'ai utilisé un objet URL à la place de Path.
Fichier
File file = new File("my_path");
URL url = file.toURI().toURL();
Ressource dans classpath utilisant classloader
URL url = MyClass.class.getClassLoader().getResource("resource_name")
Lorsque je dois lire le contenu, je peux utiliser le code suivant:
InputStream stream = url.openStream();
Et vous pouvez accéder au contenu à l'aide d'un InputStream.
Un fichier est une abstraction pour un fichier dans un système de fichiers et les systèmes de fichiers ne savent rien du contenu d'un fichier JAR.
Essayez avec un URI, je pense qu’il existe un protocole jar: // qui pourrait être utile pour vos clients.
Dans votre dossier de ressources (Java/main/resources) de votre jar, ajoutez votre fichier (nous supposons que vous avez ajouté un fichier xml nomméimports.xml), après quoi vous injectez ResourceLoader
si vous utilisez spring. comme ci-dessous
@Autowired
private ResourceLoader resourceLoader;
inside tour function écris le code ci-dessous pour charger le fichier:
Resource resource = resourceLoader.getResource("classpath:imports.xml");
try{
File file;
file = resource.getFile();//will load the file
...
}catch(IOException e){e.printStackTrace();}
private static final String FILE_LOCATION = "com/input/file/somefile.txt";
//Method Body
InputStream invalidCharacterInputStream = URLClassLoader.getSystemResourceAsStream(FILE_LOCATION);
Obtenir ceci degetSystemResourceAsStream
est la meilleure option. En obtenant le flux d'entrée plutôt que le fichier ou l'URL, fonctionne dans un fichier JAR et de manière autonome.
C'est peut-être un peu tard mais vous pouvez utiliser ma bibliothèque KResourceLoader pour obtenir une ressource de votre jar:
File resource = getResource("file.txt")
Le chemin suivant a fonctionné pour moi: classpath:/path/to/resource/in/jar
Ce n’est pas le moyen optimal de charger des ressources, at-il été précisé, mais si vous devez absolument avoir une référence Java.io.File
, essayez alors de:
URL url = null;
try {
URL baseUrl = YourClass.class.getResource(".");
if (baseUrl != null) {
url = new URL(baseUrl, "yourfilename.ext");
} else {
url = YourClass.class.getResource("yourfilename.ext");
}
} catch (MalformedURLException e) {
// Do something appropriate
}
Cela vous donne un Java.net.URL
et il peut être utilisé dans un constructeur Java.io.File
.
Dans un fichier JAR, la ressource est située absolument dans la hiérarchie des packages (pas dans le système de fichiers). Ainsi, si vous avez la classe com.example.Sweet chargeant une ressource nommée "./default.conf", le nom de la ressource est alors spécifié "/com/example/default.conf".
Mais si c'est dans un pot, alors ce n'est pas un fichier ...
Peut-être que cette méthode peut être utilisée pour une solution rapide.
public static String getResourcePath(String relativePath)
{
String pathStr = null;
URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
String codeLoaction = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
pathStr = path.toString();
}else{
//Call from IDE
pathStr = <Class>.class.getClassLoader().getResource(relativePath).getPath();
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return pathStr;
}