File.createNewFile() для относительного пути использует неверный каталог после изменения user.dir-Property

Что я пытаюсь сделать, так это создать новый файл с относительным путем в моем пользовательском каталоге после того, как я его изменил. Чтобы изменить пользовательский каталог, я использовал System.setProperty("user.dir", "/data");, затем я создал файловый объект с помощью File f2 = new File("f2"); и создал пустой файл в своей файловой системе с помощью f2.createNewFile();. После этого я ожидал, что файл появится в /data/f2, и это то, что мне говорит f2.getAbsolutePath(). Но, что сбивает с толку, файл появляется в «старом, начальном» каталоге пользователя.

Вот мой тест:

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());
        }
    }
}

Это вывод, который я получаю:

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 и f2 появляются в одном и том же каталоге, хотя я изменил user.dir между ними?


person ralfuslongus    schedule 17.02.2011    source источник
comment
возможный дубликат Java: несоответствия File.exists() при настройке user.dir   -  person Joachim Sauer    schedule 17.02.2011
comment
Да, странно, я думаю, мне нужно использовать абсолютный путь.   -  person ralfuslongus    schedule 18.02.2011


Ответы (3)


Я только что воспроизвел ваш сценарий. Я думаю, что ваша ошибка заключается в том, что вы пытаетесь использовать системное свойство для изменения текущего рабочего каталога. Возможность получить этот каталог из системного свойства — это просто метод удобства. Если вы измените свойство, сам каталог не изменится.

Решение состоит в том, чтобы создать каталог, который вы хотите, используя File.mkdir() или File.mkdirs(), а затем использовать new File(myDir, fileName), где myDir — ваш новый каталог.

person AlexR    schedule 17.02.2011
comment
Спасибо, я думаю, я должен использовать это так. - person ralfuslongus; 18.02.2011
comment
@alexr в какой-то момент, как показывает этот тест, изменение user.dir ИЗМЕНЯЕТ некоторые вещи, а не другие (это не соответствует) stackoverflow. ком/вопросы/45130661/ - person Dean Hiller; 16.07.2017

Настройка свойства user.dir не поддерживается и приводит ко всем видам странных эффектов.

person Joachim Sauer    schedule 17.02.2011

В Java невозможно изменить текущий каталог.

При изменении системного свойства изменяется свойство, но не фактический рабочий каталог, используемый собственным кодом для создания файла. Однако getAbsolutePath использует текущее значение системного каталога user.dir для составления абсолютного пути.

person JB Nizet    schedule 17.02.2011