Create file in resource / source folder in Java programmatically?

I have two resource folders.

src - here are my .java files

Resources

- here are my resource files (images, .properties) organized in folders (packages).

Is there a way to programmatically add another .properties file to this resource folder?

I tried something like this:

public static void savePropertiesToFile(Properties properties, File propertiesFile) throws IOException { FileOutputStream out = new FileOutputStream(propertiesFile); properties.store(out, null); out.close(); } 

and before that created:

 new File("/folderInResources/newProperties.properties"); 

But he is looking for this path in the file system. How to make it search in the resource folder?

EDIT . Let me tell you what it is about. I have a GUI application and I support 2 languages ​​(2 .properties files in the resources folder). Now I have added an option that the user can easily translate the application, and when he finishes, I will save these new .properties to disk in some hidden folder and read it from there. But I was hoping that I could save the new .properties files (new language) next to the current languages ​​(resource folders). I have a static message class that knows how to load resources both from disk and by default in the resource folder. But if the user takes this .jar file on some other machine, he will have such new languages, since they are located on the disk on this computer, and not inside the .jar file.

+13
source share
6 answers

As other people have noted, resources are obtained through ClassLoader. However, these two current answers could not emphasize the following points:

  • ClassLoaders are designed for the abstract process of getting classes and other resources. A resource does not have to be a file in the file system; it could be a remote url or something else that you or someone else can implement by extending java.lang.ClassLoader .
  • ClassLoaders exist in the chain of child / parent delegations. The usual behavior for ClassLoader is to first try to get the resource from the parent and only then search for its own resources, but some class loaders do the opposite (for example, in servlet containers). In any case, you will need to determine which class of the loader to receive the material in which you want to place the material, and even then another class loader above or below can "steal" your client code resource requests.
  • As Lionel Port notes, even a single ClassLoader can have multiple locations from which it loads things.
  • ClassLoaders are used to load classes. If your program can write files to the place where classes are loaded, this can easily become a security risk, because the user can enter code into your running application.

Short version: do not do this. Write a more abstract interface for the concept of "storage of resource-like things from which I can get material," and a subinterface for "storage of resource-like things from which I can get material, and also add material." Deploy the latter so that in both cases ClassLoader.getContextClassLoader().getResource() (to find the path to the classes), and if this fails, another mechanism is used to obtain information that the program could add from some location.

+7
source

Edit the main project folder of the compiled subfolders ("/ target / classes", "target / test-classes"), and you have the main way to restore the project folders with:

 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; } } 
+1
source

Java 8 solution

  Path source = Paths.get(this.getClass().getResource("/").getPath()); Path newFolder = Paths.get(source.toAbsolutePath() + "/newFolder/"); Files.createDirectories(newFolder); 

This will create a new folder in the resources folder. but you will find the new folder in the target runtime.

which will be ProjectName/target/test-classes/newFolder . if you run this code in a test case. Otherwise it would be in target/classes

Do not try to find a new folder in your src/resources . this will be required in target/test-classes or target/classes .

+1
source

Resources are loaded through the class loader, and the class loader is heavily cached by default.

You need your own class loader with the behavior you need to read resources from a non-static file system.

0
source

The problem would be that the class path may contain several root directories, so distinguishing what to store would be difficult without an existing file or directory.

If you already have an existing file uploaded.

 File existingFile = ...; File parentDirectory = existingFile.getParentFile(); new File(parentDirectory, "newProperties.properties"); 

Otherwise, try to get a handle in a directory that, as you know, is unique in your resource directory. (Not sure if this works)

 URL url = this.getClass().getResource("/parentDirectory"); File parentDirectory = new File(new URI(url.toString())); new File(parentDirectory, "newProperties.properties"); 
0
source

The following code is written to the classes directory along with class files.

As others have noted, beware of overwriting class files. It is best to put your new files in a separate directory; however, this directory must already exist. To create it, create a subdirectory in the source resources, possibly containing an empty file. For example 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(); } } 

This does the trick, but I would be nervous about deploying it outside a strictly controlled environment. I don't really like the idea of ​​unauthorized access to my classes directory!

0
source

Source: https://habr.com/ru/post/903809/


All Articles