Asked  7 Months ago    Answers:  5   Viewed   121 times

How can I change the current working directory from within a Java program? Everything I've been able to find about the issue claims that you simply can't do it, but I can't believe that that's really the case.

I have a piece of code that opens a file using a hard-coded relative file path from the directory it's normally started in, and I just want to be able to use that code from within a different Java program without having to start it from within a particular directory. It seems like you should just be able to call System.setProperty( "user.dir", "/path/to/dir" ), but as far as I can figure out, calling that line just silently fails and does nothing.

I would understand if Java didn't allow you to do this, if it weren't for the fact that it allows you to get the current working directory, and even allows you to open files using relative file paths....

 Answers

96

There is no reliable way to do this in pure Java. Setting the user.dir property via System.setProperty() or java -Duser.dir=... does seem to affect subsequent creations of Files, but not e.g. FileOutputStreams.

The File(String parent, String child) constructor can help if you build up your directory path separately from your file path, allowing easier swapping.

An alternative is to set up a script to run Java from a different directory, or use JNI native code as suggested below.

The relevant Sun bug was closed in 2008 as "will not fix".

Tuesday, June 1, 2021
 
maniclorn
answered 7 Months ago
54

To get the path of the root of the application:

//equivalent to Server.MapPath("/"); if at domain root, e.g Http://mysite.com/
string path = Server.MapPath("~");

This answer gives a rundown of a few different common Server.MapPath() uses that may also be of use to you.

Friday, August 6, 2021
 
Gaurav
answered 4 Months ago
94

I finally solved the problem.

I think it all started because the first project that I opened with pycharm was in my "download" folder, so the working directory was automatically set to a temporal folder by default and allthough I moved the project to another folder and I manually changed the working directory from the terminal, it was not working.

The solution was creating a new project and giving a correct path to the new project. It seems very easy but it was not that obvious.

Saturday, September 4, 2021
 
Alan Clark
answered 3 Months ago
17

The java.io package does not have a Directory class, but you can use the mkdir() method on the File class instead:

(new File("Foo")).mkdir()

Note that mkdir() has two separate failure modes:

  1. "If a security manager exists and its checkWrite() method does not permit the named directory to be created" then a SecurityException will be thrown.
  2. If the operation fails for another reason, mkdir() will return false. (More specifically, it will return true if and only if the directory was created.)

Point 1 is ok — if you don't have permission, throw. Point 2 is a little sub-optimal for three reasons:

  1. You need to inspect the boolean result from this method. If you ignore the result the operation could silently fail.
  2. If you get a false return you have no idea why the operation failed, which makes it difficult to recover, or formulate a meaningful error message.
  3. The strict "if and only if" wording of the contract also means that the method returns false if the directory already exists.

Aside: Contrast Point 3 with the behaviour of the .NET Directory.CreateDirectory() which does nothing if the directory exists. This kind of makes sense — "create a directory"; "ok, the directory is created". Does it matter if it was created now or earlier; by this process or another? If you really cared about that wouldn't you be asking a different question: "Does this directory exist?"

The next caveat is that mkdir() will not create more than one directory at a time. For my simple example of a directory named "Foo" this is fine; however, if you wanted to create a directory called Bar within the directory Foo (i.e. to create the directory "Foo/Bar") you must remember to use the mkdirs() method instead.

So to work around all of these caveats, you can employ a helper method such as the following:

public static File createDirectory(String directoryPath) throws IOException {
    File dir = new File(directoryPath);
    if (dir.exists()) {
        return dir;
    }
    if (dir.mkdirs()) {
        return dir;
    }
    throw new IOException("Failed to create directory '" + dir.getAbsolutePath() + "' for an unknown reason.");
}
Sunday, November 7, 2021
 
David
answered 1 Month ago
61

After some API monitoring, this is what I see

When you drop a file over a .exe file the explorer.exe uses CreateProcess API function to start the process, passing the executable as lpApplicationName, and the executable and dropped file as lpCommandLine. The lpCurrentDirectory is set in the function call by the caller process to the folder containing the dropped file[1].

When you drop a file over a .cmd file the explorer.exe also uses CreateProcess API, but in this case the lpApplicationName is null and the lplCommandLine contains the batch file and the dropped file. lpCurrentDirectory is also set to the parent folder of the dropped file[1].

When you drop a file over a .vbs file, ShellExecuteEx is used and the lpDirectory field of the SHELLEXECUTEINFO structure is null, so, the process created inherits the current active directory of the parent process. By default the current active directory of the explorer.exe process is %systemroot%system32, but it is possible to start a explorer instance with a different current active directory that will be inherited in this kind of drop operations.

[1] If we drop more than one file, the path of the file passed as first argument is used

note just for information: to test the active directory inherit the process followed was:

  • Open a cmd instance and change the current active directory to c:temp
  • Kill all explorer.exe instances
  • From the cmd instance call explorer.exe. This explorer instance has the active directory in the cmd window as its current active directory.
Tuesday, November 16, 2021
 
peixotorms
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share