How can I save a file to the class path [closed]
Asked Answered
N

6

17

How can I save / load a file that is located where my classes are? I don't the physical path to that location before and I want dynamically to find that file.

I want to load an XML file and write and read to it and I am not sure how to address it.

Nicotine answered 17/1, 2011 at 15:10 Comment(2)
Is this something you want to do during your build process (ie. ant build)?Inextinguishable
Basiclly i have an xml file i want to read and write to and i am not sure was should i put as the path to the file method.Nicotine
A
8

In the general case you cannot. Resources loaded from a classloader can be anything: files in directories, files embedded in jar files or even downloaded over the network.

Auricular answered 17/1, 2011 at 15:15 Comment(6)
I don't understand why this question is marked as right.Defunct
@RafaelRuizTabares Its a answer.Unstring
I know @karna. But the question is why? Because I think it's a empty answer. Otherwise Baluc answer is more complete.Defunct
@RafaelRuizTabares That only OP can answerUnstring
@RafaelRuizTabares totally agree with you that BalusC answer is more complete but I think I gave an answer which is that in the general case you cannot save to the classpath since it can be on any possible medium, most probably not supporting write operations.Auricular
The reason BalusC's answer is better is because it considers the concrete technical problem that the question poses, rather than the more abstract metatechnical question that is "what persistence layer is the classpath backed by?". The latter question may have some merits of its own, but it is not what is being asked here.Hypothalamus
H
40

Use ClassLoader#getResource() or getResourceAsStream() to obtain them as URL or InputStream from the classpath.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/file.ext");
// ...

Or if it is in the same package as the current class, you can also obtain it as follows:

InputStream input = getClass().getResourceAsStream("file.ext");
// ...

Saving is a story apart. This won't work if the file is located in a JAR file. If you can ensure that the file is expanded and is writable, then convert the URL from getResource() to File.

URL url = classLoader.getResource("com/example/file.ext");
File file = new File(url.toURI().getPath());
// ...

You can then construct a FileOutputStream with it.

Related questions:

Halfblooded answered 17/1, 2011 at 15:17 Comment(4)
url.toURI() - There will be NullPointerException if file doesn't exist.Newell
@naXa: That's correct. Just check beforehand if url is not null in case you're unsure. It's not different for any other Java variable which you're attempting to access using period operator .. Every self-respected Java developer knows this.Halfblooded
This answers how to update a file that exists on the classpath, but will not allow you to create a file due to getResource returning null.Sulphonamide
The counterpart of using URI, is you have to capture URISyntaxException.Ichthyology
R
13

You can try the following provided your class is loaded from a filesystem.

String basePathOfClass = getClass()
   .getProtectionDomain().getCodeSource().getLocation().getFile();

To get a file in that path you can use

File file = new File(basePathOfClass, "filename.ext");
Riddance answered 17/1, 2011 at 16:51 Comment(2)
Your code goes into the root of the project, so if you want to access a specific file in a package, just add (to your code): + "<package name>/" + fileName;Autogiro
This worked to me, others not. I would add this to the answer: File file = new File(basePathOfClass + "Filename.txt");Ichthyology
M
8

new File(".").getAbsolutePath() + "relative/path/to/your/files";

Marrano answered 17/1, 2011 at 15:14 Comment(3)
It would be nice to comment why you give answers a minus 1Marrano
It's likely because this is basically dependent on the current working directory, not on the classpath. The working directory is not the classpath root per se and, even more, this is in no way controllable from inside the program. It depends fully on the way how you started the program, thus this is too error prone.Halfblooded
Understandable, however it works good enough for me. But to each, their own.Marrano
A
8

In the general case you cannot. Resources loaded from a classloader can be anything: files in directories, files embedded in jar files or even downloaded over the network.

Auricular answered 17/1, 2011 at 15:15 Comment(6)
I don't understand why this question is marked as right.Defunct
@RafaelRuizTabares Its a answer.Unstring
I know @karna. But the question is why? Because I think it's a empty answer. Otherwise Baluc answer is more complete.Defunct
@RafaelRuizTabares That only OP can answerUnstring
@RafaelRuizTabares totally agree with you that BalusC answer is more complete but I think I gave an answer which is that in the general case you cannot save to the classpath since it can be on any possible medium, most probably not supporting write operations.Auricular
The reason BalusC's answer is better is because it considers the concrete technical problem that the question poses, rather than the more abstract metatechnical question that is "what persistence layer is the classpath backed by?". The latter question may have some merits of its own, but it is not what is being asked here.Hypothalamus
S
5

This is an expansion on Peter's response:

If you want the file in the same classpath as the current class (Example: project/classes):

URI uri = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI();
File file = new File(new File(uri), PROPERTIES_FILE);
FileOutputStream out = new FileOutputStream(createPropertiesFile(PROPERTIES_FILE));
prop.store(out, null);

If you want the file in a different classpath (Example: progect/test-classes), just replace this.getClass() with something like TestClass.class.

Read Properties from Classpath:

Properties prop = new Properties();

System.out.println("Resource: " + getClass().getClassLoader().getResource(PROPERTIES_FILE));
InputStream in = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
if (in != null) {
    try {
        prop.load(in);
    } finally {
        in.close();
    }
}

Write Properties to Classpath:

Properties prop = new Properties();
prop.setProperty("Prop1", "a");
prop.setProperty("Prop2", "3");
prop.setProperty("Prop3", String.valueOf(false));

FileOutputStream out = null;
try {
    System.out.println("Resource: " + createPropertiesFile(PROPERTIES_FILE));
    out = new FileOutputStream(createPropertiesFile(PROPERTIES_FILE));
    prop.store(out, null);
} finally {
    if (out != null) out.close();
}

Create the File Object on the Classpath:

private File createPropertiesFile(String relativeFilePath) throws URISyntaxException {
    return new File(new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()), relativeFilePath);
}
Sulphonamide answered 12/1, 2017 at 19:28 Comment(0)
S
1

According to system properties documentation, you can access this as the "java.class.path" property:

string classPath = System.getProperty("java.class.path");
Simpleton answered 17/1, 2011 at 15:15 Comment(1)
Won't be enough because it won't tell you from which part of the classpath the class is loaded from.Auricular

© 2022 - 2024 — McMap. All rights reserved.