Relative file path in java - java

I have this code:
Process p = Runtime.getRuntime().exec(command.toString(), null,
new File("D:\\Cognity"));
But the thing is the Cognity directory is not always in D:\, it could be in C:\ etc. So my question is if there is a way to give it a relative path so I don't have to change this code depending on the PC that uses the program?

As System.getProperty("user.dir")); returns the directory from which the JVM was launched you still can't guarantee whether you're in C:\ or D:\
My advice would be to pass the Cognity location in as a -D commandline argument and use it like this:
Process p = Runtime.getRuntime().exec(command.toString(), null, new File(System.getProperty("cognity.dir")));

Call System.getProperty("user.dir"); to get your current dir, and concat the relative path to the result.
e.g.
String path = System.getProperty("user.dir");
path += relativePath;
EDIT:
Clarification:
For example:
The program you want to run is always located two folders backwards, and then at Temp dir.
So the relative path is ..\\..\Temp\prog.exe.
Let's say that in one computer you have your program located at C:\Users\user\Documents\Program, so this is the working directory.
So:
String path = System.getProperty("user.dir"); //returns the working directory
String relativePath = "\\ ..\\..\\Temp"; //no matter what is the first path, this is the relative location to the current dir
path += relativePath;
//in this example, path now equals C:\Users\user\Documents\Program\..\..\Temp\prog.exe = C:\Users\user\Temp\prog.exe
Process p = Runtime.getRuntime().exec(command.toString(), null, new File(path));

You could use a config-File to set the absolute-path or you create that directory in a relative path to the jar-file.

Related

Get path of file without drive letter - Windows 10 / Java 8

Windows 10
Java 8
When I call getCanonicalPath on a File object, I get a string like this
C:\data\processed\Test.xml
How do I get the same string but without C:\ and if possible also with / instead of \?
You can use NIO.2 API and its objects Path and Paths which is a abstraction over a file system.
Path path = Paths.get("C:\\data\\processed\\Test.xml");
You can also get Path from File using File::toPath. Actually, you need to get all the names in the path:
File file = new File("C:\\data\\processed\\Test.xml");
Path path = file.toPath();
int count = path.getNameCount(); // the count of names
path = path.subpath(0, count); // all the names
Alternatively (thanks to #Holger) using Path:relativize (you find a relative path to the root C:/ which is all the names.
File file = new File("C:\\data\\processed\\Test.xml");
Path path = file.toPath();
path = path.getRoot().relativize(path);
Here are some relevant methods:
path.getRoot() returns C:\
path.getNameCount() returns the number of name elements in the path (3 in this case)
path.getName(0) returns data, path.getName(1) returns processed etc...
path.subpath(fromInclusive, toExclusive) returns a relative Path that is a subsequence of the name elements of this path.
path.relativize(path) returns a relative path to a parameter.
The object Path represents an abstraction of the actual path. If you want to replace \ with / as a String, you might need to use String::replace.
String stringPath = path.toString().replace('\\', '/');
System.out.println(path); // data\processed\Test.xml
System.out.println(stringPath); // data/processed/Test.xml
Here is a short answer:
File file = new File("c:\\tmp\\abc.txt"); //file =C:\tmp\abc.txt
String filePath= file.getCanonicalPath(); //path= C:\tmp\abc.txt
String str=filePath.replace('\\', '/'); //str= C:/tmp/abc.txt
java.net.URI uri= new java.net.URI(str); //uri= C:/tmp/abc.txt
uri.getPath(); //uri.getPath() = /tmp/abc.txt

Relative path to database file in Java

I have to access a database file in my Java project but I can't get the path right.
The full path is C:\Hogwarts\db\hogdb.fdb.
I tried to use this code line to find the the current relative path:
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + s);
and it says the current relative path is: C:\Hogwarts.
Right now my code looks like this :
minDataBas = new InfDB("db\\HOGDB.FDB");
new HuvudFonster(minDataBas).setVisible(true);
What am I missing?
In fact all elements are there; just use an absolute path.
String cwd = System.getProperty("user.dir"); // Alternative
Path cwdPath = Paths.get(cwd);
Path dbPath = Paths.get(cwd, "db/hogdb.fdb");
String db = dbPath.toAbsolutePath().toString();
if (!Files.exists(dbPath)) {
throw new IllegalStateException("Wrong path for database: " + db);
}
minDataBas = new InfDB(db);
From the InfDB.java file:
#param path Path to the Firebird DB, for example C:/DB.FDB or for Mac /User/DB.FDB
Providing the absolute path, as opposed to relying on the method inferring you are using a relative path, should resolve the issue. Hence, use:
minDataBas = new InfDB("C:\\Hogwarts\\db\\HOGDB.FDB");
or if you know that the database file will be similarly relative to the current working directory for wherever it has launched, you could use the previously found working directory path and append the remaining location as such
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
minDataBas = new InfDB(s + "\\db\\HOGDB.FDB");
If you cannot be sure where the file will there are a variety of techniques you could use to have the user define where the file is. Setting a path variable, configuration files or simply taking user input.
I think instead it should be
minDataBas = new InfDB("C:\\Hogwarts\\db\\HOGDB.FDB");

relative file path not working in Java

After reading that is it possible to create a relative filepath name using "../" I tried it out.
I have a relative path for a file set like this:
String dir = ".." + File.separator + "web" + File.separator + "main";
But when I try setting the file with the code below, I get a FileNotFoundException.
File nFile= new File(dir + File.separator + "new.txt");
Why is this?
nFile prints: "C:\dev\app\build\..\web\main"
and
("") file prints "C:\dev\app\build"
According to your outputs, after you enter build you go up 1 time with .. back to app and expect web to be there (in the same level as build). Make sure that the directory C:\dev\app\web\main exists.
You could use exists() to check whether the directory dir exist, if not create it using mkdirs()
Sample code:
File parent = new File(dir);
if(! parent.exists()) {
parents.mkdirs();
}
File nFile = new File(parent, "new.txt");
Note that it is possible that the file denoted by parent may already exist but is not a directory, in witch case it would not be possible to use it a s parent. The above code does not handle this case.
Why wont you take the Env-Varable "user.dir"?
It returns you the path, in which the application was started from.
System.getProperty(user.dir)+File.separator+"main"+File.separator+[and so on]

Moving to a directory one level down

Is it possible to move to a directory one level down in Java?
For example in command prompt:
C:\Users\foo\
I can use cd.. to go to:
C:\Users\
Is it possible to do this in Java, because I'm getting a directory using System.getProperty("user.dir"); however that is not the directory I'd want to work at, but rather 1 level down the directory.
I have thought of using the Path class method; subpath(i,j), but if the "user.dir" were to be changed to another directory, then the returned subpath would be different.
The File class can do this natively.
File upOne = new File(System.getProperty("user.dir")).getParentFile()
http://docs.oracle.com/javase/6/docs/api/java/io/File.html#getParentFile%28%29
On my system, the ".." is a valid component of a path.
Here is an example.
File file;
String userDir = System.getProperty("user.dir");
file = new File(userDir);
System.out.println(file.getCanonicalPath());
file = new File(userDir+"/..");
System.out.println(file.getCanonicalPath());
Output is:
C:\ano\80g\workaces\_JAV_1.0.0\CODE_EXAMPLE
C:\ano\80g\workaces\_JAV_1.0.0
As the previous answers have pointed out, you can do this using File. Alternatively, using the Java 7 NIO classes, as you appear to be doing, the following should do the same:
Paths.get(System.getProperty("user.dir") + "/..").toRealPath();
Note that "/" is a valid directory separator on the Windows file system as well (though I tested this code on Linux).
private static void downDir(int levels) {
String oldPath = System.getProperty("user.dir");
String[] splitedPathArray = oldPath.split("/");
levels = splitedPathArray.length - levels;
List<String> splitedPathList = Arrays.asList(splitedPathArray);
splitedPathList = splitedPathList.subList(0, levels);
String newPath = String.join("/", splitedPathList);
System.setProperty("user.dir", newPath);
}
Should work. For the levels, just specify 1.

Find Path During Runtime To Delete File

The code basically allows the user to input the name of the file that they would like to delete which is held in the variable 'catName' and then the following code is executed to try and find the path of the file and delete it. However, it doesn't seem to work, as it won't delete the file this way. Is does however delete the file if I input the whole path.
File file = new File(catName + ".txt");
String path = file.getCanonicalPath();
File filePath = new File(path);
filePath.delete();
If you're deleting files in the same directory that the program is executing in, you don't need specify a path, but if it's not in the same directory that your program is running in and you're expecting the program to know what directory your file is in, that's not going to happen.
Regarding your code above: the following examples all do the same thing. Let's assume your path is /home/kim/files and that's where you executed the program.
// deletes /home/kim/files/somefile.txt
boolean result = new File("somefile.txt").delete();
// deletes /home/kim/files/somefile.txt
File f = new File("somefile.txt");
boolean result = new File(f.getCanonicalPath()).delete();
// deletes /home/kim/files/somefile.txt
String execPath = System.getProperty("user.dir");
File f = new File(execPath+"/somefile.txt");
f.delete();
In other words, you'll need to specify the path where the deletable files are located. If they are located in different and changing locations, then you'll have to implement a search of your filesystem for the file, which could take a long time if it's a big filesystem. Here's an article on how to implement that.
Depending on what file you want to delete, and where it is stored, chances are that you are expecting Java to magically find the file.
String catName = 'test'
File file = new File(catName + '.txt');
If the program is running in say C:\TestProg\, then the File object is pointing to a file in the location C:\TestProg\test.txt. Since the file object is more of just a helper, it has no issues with pointing to a non-existent file (File can be used to create new files).
If you are trying to delete a file that is in a specific location, then you need to prepend the folder name to the file path, either canonically, or relative to the execution location.
String catName = 'test'
File file = new File('myfiles\\'+ catName +'.txt');
Now file is looking in C:\TestProg\myfiles\test.txt.
If you want to find that file anywhere, then you need a recursive search algorithm, that will traverse the filesystem.
The piece of code that you provided could be compacted to this:
boolean success = new File(catName + ".txt").delete();
The success variable will be true if the deletion was successful. If you do not provide the full absolute path (e.g. C:\Temp\test for the C:\Temp\test.txt file), your program will assume that the path is relative to its current working directory - typically the directory from where it was launched.
You should either provide an absolute path, or a path relative to the current directory. Your program will not try to find the file to delete anywhere else.

Categories