relative path in Java - java

My program has to use certain files that reside in another directory. Right now I am using absolute path to specify the location of the files. But I know that the relative position of these files will remain the same compared to where my program is residing. How I can use relative path in Java to specify the location of these files?
For example my program is residing in
/home/username/project/src/com/xyz/
..and the target files are in..
/home/username/project/secure/

For example my program is residing in /home/username/project/src/com/xyz/
and the target files are in /home/username/project/secure/
Knowing the place where your program's source code resides does not help. What you need to know is the current directory of the program when it is executed. That could be literally anything. Even if you are launching the application from (for example) Eclipse, the application launcher allows you to specify the "current directory" for the child process in the Run configuration.

Your current path.
currentPath= /home/username/project/src/com/xyz/;
Relative path to "/home/username/project/secure/" folder is
relativePath= ../../../secure;

In Java you can use getParentFile() to traverse up the tree.
File currentDir = new File(".");
File parentDir = currentDir.getParentFile();
This will be safe as you are not using system dependent file separator (../)

Related

Java can't get relative path for file

Image DescriptionTrying to access a test.txt file that is in the same location as my HelloController.java file but for some reason, it is showing that the file does not exist. I've tried moving the file around but it does not work.
Using the absolute path works, but this is a shared project so it will be ran on other computers. Any suggestions would be much appreciated.
Your best bet is to add it to the class path and reading it as a class path resource.
The relative path root is your "working directory". Which means if you try to access "." you will start at your working directory. This directory is only set once for your application and is normally the folder which was opened when you started it.
When working with IDEs (like in your case) the working directory will be the root folder of your project (So the folder in which the pom.xml and src folders are located.
If you want to access the file via the normal file API you are currently using, just put the file in that diretory and it should work (given you share it with the other people in the same location).
If you need the file to be inside your generated output jar-file, you will need to use the File as a resource (See duffymo's answer), as the file does not exist by itself on the file system, but as a file inside your jar-file.
If you want to know your current working directory, you can create a File refrence to "." and expand it to an absolute path (Which will replace refrences like "." and ".." and generate a file path from your root) and then write it to the console. This would look something like this:
// Get refrence to the current working directory
File workingDirectoryReference = new File(".");
// Convert it to an absolute path string
String absolutePath = workingDirectoryReference.getAbsolutePath();
// Output to console
System.out.println(absolutePath );

Java file path f.exists() always returns false

I'm trying to create a basic Java program that allows the user create files and folders.
I want all this to happen in a folder inside my project (image attached) so I've got some doubts...
This would be my proyect tree
Is the folder "Test" correctly placed? if not how do i access to it? As you see, it's inside com.company, should I move it to src?
When I try to check if exists, it says false.
This is my code:
public class Main {
Scanner input = new Scanner(System.in);
public static void main(String[] args) {
Main main = new Main();
main.init();
}
public void init(){
File f = new File("Test"); //Here i've tried "com"+File.separator+"company"+File.separator+"Test"
System.out.println(f.exists()); //output is false here
}
}
f.getParent() says null.
But when I try: System.out.println(f.getAbsolutePath()); it shows correctly the whole path.
The point of using relative path is because i'd like this code to work on ANY computer.
Thanks in advice, hope someone could help me a bit.
If you use relative pathnames in Java, they will be resolved relative to the running application's working directory. So you need to know what the working directory is going to be.
When you are launching an application in an IDE, the working directory depends on the IDE and the launcher configs. But it is typically the file system directory that corresponds to the top of the project.
Another thing to note is that the src folder you see is special. The entries in it are typically not files and directories. The are typically Java packages and classes. So in the file system, "src" > "com.company" > "Main" is actually represented as a file with the path "src/com/company/Main.java".
This means that it is kind of wrong to put arbitrary folders and files into the "src" folder. It will work ... but it is conceptually wrong. Data files don't belong in the source tree, and certainly not data files written by your application. (And when you start using a source control system, you will find that writing data files into your source tree is going to give you a headache. I won't go into details ... but I am pretty sure that you would regret it.)
The other thing that is conceptually wrong about what you are doing is that Java programs are normally written to be free standing things. The user of your program should not need to download and install Intellij or some other IDE and load your project into it. They will want to just run it from a JAR file. In that world, the project directory and the "src" folder won't exist, and hardwiring relative paths like "src/Test" will be problematic.
So lets ignore that for now and look at what your code is currently doing
Is the folder "Test" correctly placed? if not how do i access to it? As you see, it's inside com.company, should I move it to src?
According to the image, the Test folder (actually package) >>is<< in the src Folder.
When I try to check if exists, it says false.
Your code is using the wrong path. With the "Test" folder places where you have it (according to the picture!), the relative path should be "src/Test", not "Test" or "com/company/Test".
Note that Windows accepts either "/" or "\" will work as a file separator, even though "\" is what is used conventionally.
f.getParent() says null.
That is correct. The relative path "Test" does not have a parent part. It is a simple file / directory name.
Think of it this way. Until a File with a relative path is resolved, it is not determined what directory it is relative to.
But when I try: System.out.println(f.getAbsolutePath()); it shows correctly the whole path.
Again, correct.
When you call f.getAbsolutePath() on a relative File, the runtime system prepends the path of the application's working directory, and then gives you the result.
The point of using relative path is because I'd like this code to work on ANY computer.
That relative path will NOT work on ANY computer. You are using a path that is within your project's src tree, and your project typically won't exist on an end-user's computer. (See above.)
So what should you do?
There is no single correct answer.
You could put the file / directory into the user's current / working directory.
You could put the file / directory into the user's home directory, or a hidden subdirectory in the home directory. (This is a common approach on Linux.)
You could make the pathname for the directory a command line argument
You could get the pathname from an environment variable
You could get the pathname from an application specific config file.
The best answer will depend on the context.
According to your picture the path is wrong, you should check inside the src directory:
File f = new File("src/Test");
System.out.println(f.exists());

Relative path using Level hierarchy(../../)

I want to use the relative path in xml files in our project. I have the files in the following location.
D:/SDC-Builds/SRDM2.3.0/SRDM/Svr/IdP/IdPserver/conf/attribute-r.xml
I have other xml file which needs to ref the above location, I use the following relative path to be independent of machines and folder names.
In D:/SDC-Builds/SRDM2.3.0/SRDM/Svr/IdP/IdPserver/others/service.xml, i am using the code like below
service.xml
<srv:ConfigurationResource="../../../../../../IdP/IdPserver/conf/attribute-r.xml">
</srv>
Please tell me am i using proper convention to refer the attribute-r.xml ?
If your Project Root Directory is SRDM, then you need to get back from your executable path.
Say you have your exe file at SRDM/Svr/bin/EXECUTABLE.exe then,
you need to mention in xml as
<srv:ConfigurationResource="../IdP/IdPserver/conf/attribute-r.xml"></srv>
ie. Current working directory is SRDM/Svr/bin/ and from that you need to get back up to common junction[Svr] in your case.

Start my application from my home folder (relative path)

This is a 100% win console application.
So here's the problem.
I want to load the file music.xm that I want to place inside the jar.
The problem come up when I try to call the file through a relative path. The start directory it's not the Java project one, but my Windows User Folder.
If I call
File music = new File("\\music.xm");
javax.sound.sampled.UnsupportedAudioFileException: /C:/Users/XXXX/Desktop/./music/music.xm
If I call
File music = new File(".\\music.xm");
I get
javax.sound.sampled.UnsupportedAudioFileException: /C:/music.xm
If its in your jar, you can use
getclassLoader().getResourceAsStream("music.xm")
You can use this inputStream however you like. But remember, the path should be relative to classpath root of the classloader.
In addition, if you are sure "music.xm" exists as an independent file on filesystem in a fixed relative location to your .class files you can also use :
getclassLoader().getResource("music.xm")
You can look on SO and here for documentation.

Java FileOutputStream Default Creation Path

Let's say I have below code:
String fileName = "name.txt";
FileOutputStream fileOut = new FileOutputStream(fileName);
wb.write(fileOut);
This way, the file will be created under bin folder of the project.
However, if I specific fileName at a whole path:
String fileName = "c:/temp/name.txt";
this file will be created at c:\temp folder.
Am Correct? And Why this happen, how FileOutputStream work?
It's not about how FileOutputStream works, it's about the path that the operating system assigns to a process when it starts it
This path is called current working directory. From that directory all relative paths are calculated. A simple file name is a relative path (to the current working directory).
If you specify an absolute path then this path is used to create the file.
You can read more about paths on this wiki page.
If you don't specify an absolute path, e.g. if you only specify the file name, then your program or the operating system somehow needs to figure out, where to find that file. For that reason a running program always has a working directory. That happens to be the folder you start it from, by default.
Unless you specify an absolute path, the path is relative to current working directory.
If your current working directory is a bin folder in your project, it will be created there.
If you only specify the filename, it will be created in the current working directory. If you do specify an absolute path, it will of course be created at that path.
It's all about relative and absolute directories. Let's say that you specif path foo/bar. It'll create a file bar in foo directory of your working folder. The same applies for ../foo/bar it'll create a bar file in foo directory in the folder above the working dir. However, if you type C:\\Documents\ and\ Settings\User\Desktop\bar (or /home/user/Desktop/bar), it'll create a bar on your desktop. For more info take a look here.

Categories