J'ai deux dossiers de ressources.
src - voici mes fichiers .Java
ressources - voici mes fichiers de ressources (images, .properties) organisés en dossiers (packages).
Existe-t-il un moyen d'ajouter par programme un autre fichier .properties dans ce dossier de ressources?
J'ai essayé quelque chose comme ça:
public static void savePropertiesToFile(Properties properties, File propertiesFile) throws IOException {
FileOutputStream out = new FileOutputStream(propertiesFile);
properties.store(out, null);
out.close();
}
et avant que créé:
new File("/folderInResources/newProperties.properties");
Mais il recherche ce chemin sur le système de fichiers. Comment puis-je le forcer à regarder dans le dossier des ressources?
EDIT: Laissez-moi vous dire de quoi il en retourne. J'ai une application graphique et je supporte 2 langues (2 fichiers .properties dans le dossier des ressources). Maintenant, j'ai ajouté une option permettant à l'utilisateur de traduire facilement une application. Une fois l'opération terminée, j'enregistre ce nouveau fichier .properties sur un disque situé dans un dossier caché, puis je le lis à partir de là. Mais j'espérais pouvoir enregistrer ces nouveaux fichiers .properties (nouvelle langue) à côté des langues actuelles (dossier de ressources). J'ai une classe statique de messages qui sait comment charger des ressources à la fois du disque et des valeurs par défaut dans le dossier des ressources. Mais si l'utilisateur prend ce fichier .jar sur une autre machine, il n'aura pas cette nouvelle langue puisqu'il se trouve sur le disque de cet ordinateur et non à l'intérieur du fichier .jar.
Comme d'autres personnes l'ont mentionné, les ressources sont obtenues via un ClassLoader. Ce que les deux réponses actuelles ont toutefois omis de souligner, ce sont les points suivants:
Java.lang.ClassLoader
.Version courte: ne le faites pas. Ecrivez une interface plus abstraite pour le concept de "référentiel d'éléments de type ressources dont je peux obtenir des éléments" et une sous-interface pour "un référentiel d'éléments de type ressources dont je peux obtenir des éléments, mais aussi ajouter des éléments". Implémentez ce dernier de manière à utiliser ClassLoader.getContextClassLoader().getResource()
(pour rechercher dans le chemin de classe) et, en cas d'échec, à utiliser un autre mécanisme pour obtenir des éléments que le programme peut avoir ajoutés à partir d'un emplacement donné.
Coupez le dossier de projet principal des sous-dossiers compilés ("/ target/classes", "target/test-classes") et vous aurez le chemin de base pour reconstruire vos dossiers de projet avec:
import Java.io.File;
import Java.io.IOException;
import Java.net.URISyntaxException;
public class SubfolderCreator {
public static void main(String... args) throws URISyntaxException, IOException {
File newResourceFolder = createResourceSubFolder("newFolder");
}
private static File createResourceSubFolder(String folderName) throws URISyntaxException, IOException {
Java.net.URL url = SubfolderCreator.class.getResource("/EXISTING_SUBFOLDER/");
File fullPathToSubfolder = new File(url.toURI()).getAbsoluteFile();
String projectFolder = fullPathToSubfolder.getAbsolutePath().split("target")[0];
File testResultsFolder = new File(projectFolder + "src/test/resources/" + folderName);
if (!testResultsFolder.exists()) {
testResultsFolder.mkdir();
}
return testResultsFolder;
}
}
Le problème serait que le chemin de classe peut contenir plusieurs répertoires racine afin de distinguer celui à stocker serait difficile sans un fichier ou un répertoire existant.
Si vous avez un fichier existant chargé.
File existingFile = ...;
File parentDirectory = existingFile.getParentFile();
new File(parentDirectory, "newProperties.properties");
Sinon, essayez d'obtenir un identifiant sur un répertoire que vous savez être unique dans votre répertoire de ressources. (Pas sûr si cela fonctionne)
URL url = this.getClass().getResource("/parentDirectory");
File parentDirectory = new File(new URI(url.toString()));
new File(parentDirectory, "newProperties.properties");
Le code suivant écrit dans le répertoire classes
, avec les fichiers de classe.
Comme d'autres l'ont noté, méfiez-vous des fichiers de classe d'écrasement. Il est préférable de placer vos nouveaux fichiers dans un répertoire séparé. Cependant, ce répertoire doit déjà exister. Pour le créer, créez un sous-répertoire au sein des ressources de la source, contenant peut-être un fichier vide. Par exemple src\main\resources\dir\empty.txt
.
public class WriteResource {
public static void main(String[] args) throws FileNotFoundException {
String thing = "Text to write to the file";
String dir = WriteResource.class.getResource("/").getFile();
//String dir = WriteResource.class.getResource("/dir").getFile();
OutputStream os = new FileOutputStream(dir + "/file.txt");
final PrintStream printStream = new PrintStream(os);
printStream.println(thing);
printStream.close();
}
}
Cela fait l'affaire, mais je serais inquiet de le déployer en dehors d'un environnement strictement contrôlé. Je n'aime pas trop l'idée que des personnes non autorisées écrivent dans mon répertoire classes
!
Les ressources sont chargées via un chargeur de classes et le chargeur de classes par défaut met fortement en cache.
Vous avez besoin de votre propre chargeur de classes avec le comportement dont vous avez besoin pour lire les ressources d'un système de fichiers non statique.