I can use:
getClass().getClassLoader().getResource("").getPath());
To dynamically get the path of the Class files in my project.
But I need to get the path dynamically for the home directory of the project. I can't do this statically, like this:
File file = new File("C:\Users\etc...");
Because the destination of the project can change from one computer to the next. I need to call a file in the project's home directory. How do I do that dynamically. It would be similar to how I did it in the beginning of this question, but it can not be just for Classes.
Any idea?
There's no such thing as a "java project" in Java. If you know where your class files are in relationship to whatever directory you're trying to locate, you can use the path you obtained in your first example:
Url classUrl = ...
File resourcePath = new File(classUrl.toUri());
File rootDir = resourcePath.getParentFile().getParentFile().getParentFile();
or
File rootDir = new File(resourcePath.getPath() +
"/../../../".replace("/", File.separatorChar));
Of course, this will only work as long as the files are actually on the file system; if they're in a jar, you'd need to locate the jar file instead.
But this is usually not something you want to do. It's a better practice to configure a sandbox for your application by passing them to your application as command-line arguments or environment variables. In some cases, it's also useful to use the pre-defined System properties such as user.home, user.dir, and java.io.tmpdir.
Related
I have created a .txt file in my Eclipse Java project, and I want to find out the path to it so I can use it for a Scanner. I do not want to find out the path on my local drive, as I will be planning to share the program to someone else, and they will have a different folder structure, rather a path that can be used on anybodies machine.
Here is the code:
this.file = new File("<insert path here>");
you can use :
= new File("Build Path"); (your .java file exist in your build path)
The build path is used for building your application. It contains all of your source files and all Java libraries that are required to compile the application.
In eclipse, the default behavior is for the Java system property user.dir to be set to the project directory. This is what dictates where the "root" of File operations is. So if you created a file test.txt in the root project directory, you should be able to access it with new File("test.txt").
However, as Andrew Thompson mentioned in his comment, the more correct method would be using embedded resources.
Try one of These:
1.
System.getProperty("user.dir");
2.
File currentDirFile = new File(".");
String helper = currentDirFile.getAbsolutePath();
String currentDir = helper.substring(0, helper.length() - currentDirFile.getCanonicalPath().length());//this line may need a try-catch
I have not tested it just found while googling
I have a maven project with these standard directory structures:
src/main/java
src/main/java/pdf/Pdf.java
src/test/resources
src/test/resources/files/x.pdf
In my Pdf.java,
File file = new File("../../../test/resources/files/x.pdf");
Why does it report "No such file or dirctory"? The relative path should work. Right?
Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.
The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.
Why does it report "No such file or dirctory"? The relative path should work. Right?
wrong.
Your classes are compiled to $PROJECT_ROOT/target/classes
and your resources are copied to the same folder keeping their relative paths below src/main/resources.
The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:
File file = new File("/files/x.pdf");
Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).
But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.
No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file.
Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.
Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("<path in classpath>");
Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.
I've got a project to do with 2 other classmates.
We used Dropbox to share the project so we can write from our houses (Isn't a very good choice, but it worked and was easier than using GitHub)
My question is now about sharing the object stream.
I want to put the file of the stream in same dropbox shared directory of the code.
BUT, when i initialize the file
File f = new File(PATH);
i must use the path of my computer (C:\User**Alessandro**\Dropbox)
As you can see it is linked to Alessandro, and so to my computer.
This clearly won't work on another PC.
How can tell the compiler to just look in the same directory of the source code/.class files?
You can use Class#getResource(java.lang.String) to obtain a URL corresponding to the location of the file relative to the classpath of the Java program:
URL url = getClass().getResource("/path/to/the/file");
File file = new File(url.getPath());
Note here that / is the root of your classpath, which is the top of the directory containing your class files. So your resource should be placed inside the classpath somewhere in order for it to work on your friend's computer.
Don't use absolute paths. Use relative paths like ./myfile.txt. Start the program with the project directory as the current dir. (This is the default in Eclipse.) But then you have to ensure that this both works for development and for production use.
As an alternative you can create a properties file and define the path there. Your code then only refers to a property name and each developer can adjust the configuration file. See Properties documentation.
In C#,when I want to create a configuration file, it's so easy,just right click the mouse and add a new configuration file, this file will be added into the solution and it's so easy to maintain.
But in java, I don't know what method is standard. I see some people use the properites file.If this is the most popular method, can some one tell me where to place this file? I saw some guy put it in the src folder, others put it in an external folder.
Can you tell me which is the standard? And what is the best practice to maintain a configuration.
I don't know if this is the "standard" way but I think it's the easiest. If you place your properties file in your project's root folder
- project
- config.properties
- src
- main
- ...
- test
When you create a File instance in Java and specify a relative filename, then the name is resolved against the directory that Java was launched from
e.g. if you launch java in your command prompt as follows:
cd C:\Users\Tom\example-project
java example-project
and this is your code:
File file = new File("tom.txt");
then the file variable will be resolved to the abolsute path: C:\Users\Tom\example-project\tom.txt
When you Run a project through Eclipse, Eclipse launches java from the root directory of the project, meaning that if you put your config file in the project's root folder then
File file = new File("name-of-config-file.properties");
will resolve to the correct config file on your system.
This has an added benefit if you create a runnable JAR, as you can just place your config file in the same directory as your JAR and the code will continue to work (the config file location will be resolved relative to the JAR).
If you put your config file in /src folder then you need to have separate code for when running from Eclipse and when running as a JAR
With regards to sample code:
//Read properties from disk
File propertiesFile = new File("config.properties");
FileReader reader = new FileReader(propertiesFile);
Properties props = new Properties();
props.load(reader);
//Set and get properties
props.setProperty("NewProperty", "value");
String propValue = props.getProperty("propToGet");
//Write properties to disk
FileWriter writer = new FileWriter(propertiesFile);
props.store(writer, "Added x properties");
Configuration files are used to store,read write user settings.
I think for web apps you can use web.xml.And for other you should use Properties class to read and write settings.
As for where to place it,If you dont specify path it is stored in your root folder other than that you have to provide explicit path.
Say I have an exported Jar file on my Desktop, and then a folder I want to access so my jar file can load files from it. How can I access that folder without hard coding the path?
See here: https://stackoverflow.com/a/6849255/514463
Pick one of your classes that you want the directory of, e.g.: Test:
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
If I clearly understand, you may use relative path when you try to access folder. For example, if you run your jar as a standalone application, relative path "." will be a folder that contains your jar. So, when you place names.txt file next to your jar, you can get access to it with:
new File("./names.txt");
Hope I understood you right way and this will help.
The following code should provide the directory containing the JAR file:
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
File directory = new File(url.toURI()).getParentFile();
Hmmm...
I heard this question so often, and it always boils down to this: How to load resources at runtime?
The main reason for this type of question is, that one is developping an application and now wants to create a distributable package. This normally ends in something like that:
... / my-application-folder
| -- lib / *.jar
| -- main.jar
| -- config.properties
There could be several configuration files. A configuration for the application itself, a configuration for a logging framework that is used, etc. It does not matter. If you want to access such resources, you should do it in two steps:
1) Make sure all folders containing your resources (such configuration files are resources) are part of the classpath. If you run your JAR file (here main.jar) with a java -jar main.jar command, this JAR file should contain a manifest file containing the directory . and all needed library JARs in the class-path entry. [Alternative: Maybe all your config files are located in a config/ subfolder. Then this folder must be part of the class-path.]
2) Inside your application you access such resources with a class loader:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource(neededResource);
// do something with url, e.g. open stream, read from it, and close stream
If you have a user customizable path, there are several possibilities. You could for example pass a system property to the application, as Reddy suggested in his comment. You could also have a property in a configuration file, which you are loading in the beginning part of your application. However, you have the path to this customizable folder in hand (at runtime). Then you do the following:
String customizablePath = getCustomizablePath();
URL customizablePathURL = new File(customizablePath).toURI().toURL();
ClassLoader loader = new URLClassLoader(new URL[] {customizablePathURL});
Then you can continue like above.
File f = new File("Folder")
This File object points to "Folder" directory in the the working directory of the Jar.