File.createNewFile() for relative path uses wrong directory after changing "user.dir"-Property

2.6k views Asked by At

What I am trying to do is to create a new File with relative path in my user-directory after I changed it. To change the user-directory I used System.setProperty("user.dir", "/data");, then I created a file-object with File f2 = new File("f2"); and created the empty file on my filesystem with f2.createNewFile();. After this I expected the file to appear in /data/f2, and this is what f2.getAbsolutePath() tells me. But, confusingly, the file appears in the "old, initial" userDir.

Here is my Test:

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

public class Main {

    private static FilenameFilter filter = new FilenameFilter() {

        public boolean accept(File dir, String name) {
            return (name.startsWith("f")) ? true : false;
        }
    };

    public static void main(String[] args) throws IOException {
        String userDirPropertyName = "user.dir";
        File initialUserDir = new File(System.getProperty(userDirPropertyName));

        System.out.println("files in " + initialUserDir.getAbsolutePath() + ":");
        for (File file : initialUserDir.listFiles(filter)) {
            System.out.println("  - " + file.getAbsoluteFile());
        }

        System.out.println("initial userDir = " + System.getProperty(userDirPropertyName));
        File f1 = new File("f1");
        f1.createNewFile();
        System.out.println("f1.getAbsolutePath() = " + f1.getAbsolutePath());
        System.out.println("getCanonicalPath() for . = " + new File(".").getCanonicalPath());

        System.setProperty(userDirPropertyName, "/data");

        System.out.println("changed userDir = " + System.getProperty(userDirPropertyName));
        File f2 = new File("f2");
        f2.createNewFile();
        System.out.println("f2.getAbsolutePath() = " + f2.getAbsolutePath());
        System.out.println("getCanonicalPath() for . = " + new File(".").getCanonicalPath());


        System.out.println("files in " + initialUserDir.getAbsolutePath() + ":");
        for (File file : initialUserDir.listFiles(filter)) {
            System.out.println("  - " + file.getAbsoluteFile());
        }
    }
}

This the output, that I get:

files in /home/pps/NetBeansProjects/UserDirTest:  
initial userDir = /home/pps/NetBeansProjects/UserDirTest  
f1.getAbsolutePath() = /home/pps/NetBeansProjects/UserDirTest/f1  
getCanonicalPath() for . = /home/pps/NetBeansProjects/UserDirTest  
changed userDir = /data  
f2.getAbsolutePath() = /data/f2  
getCanonicalPath() for . = /data  
files in /home/pps/NetBeansProjects/UserDirTest:  
  - /home/pps/NetBeansProjects/UserDirTest/f1  
  - /home/pps/NetBeansProjects/UserDirTest/f2

f1 and f2 appear in the same directory though I changed the user.dir in between?

3

There are 3 answers

2
AlexR On

I have just reproduced your scenario. I think that your mistake is that your are trying to use system property to change current working directory. Ability to retrieve this directory from system property is just a convenience method. If you change the property the directory itself is not being changed.

The solution is to create directory your want using File.mkdir() or File.mkdirs() and then use new File(myDir, fileName) where myDir is your new directory.

0
Joachim Sauer On

Setting of the property user.dir is not supported and leads to all kinds of strange effects.

0
JB Nizet On

There is no way to change the current directory in Java.

When you change the system property, the property is changed, but not the actual working directory, used by native code to create the file. getAbsolutePath, however, uses the current value of the user.dir system directory to compose the absolute path.