Подтвердить что ты не робот

Объединение путей в Java

В Python Я могу присоединиться к двум путям с помощью os.path.join:

os.path.join("foo", "bar") # => "foo/bar"

Я пытаюсь добиться того же самого в Java, не беспокоясь, если OS Unix, Solaris или Windows:

public static void main(String[] args) {
    Path currentRelativePath = Paths.get("");
    String current_dir = currentRelativePath.toAbsolutePath().toString();
    String filename = "data/foo.txt";
    Path filepath = currentRelativePath.resolve(filename);

    // "data/foo.txt"
    System.out.println(filepath);

}

Я ожидал, что Path.resolve( ) присоединится к моему текущему каталогу /home/user/test с помощью data/foo.txt, сделав /home/user/test/data/foo.txt. Что я ошибаюсь?

4b9b3361

Ответ 1

Несмотря на то, что исходное решение для получения текущего каталога с помощью empty String работает. Но рекомендуется использовать свойство user.dir для текущего каталога и user.home для домашнего каталога.

Path currentPath = Paths.get(System.getProperty("user.dir"));
Path filePath = Paths.get(currentPath.toString(), "data", "foo.txt");
System.out.println(filePath.toString());

выход:

/Users/user/coding/data/foo.txt

Из Java Path класс Документация:

Путь считается пустым, если он состоит только из одного элемента name, который empty. Доступ к файлу с помощью empty path is equivalent to accessing the default directory файловой системы.


Почему Paths.get("").toAbsolutePath() работает

Когда пустая строка передается в Paths.get(""), возвращаемый объект Path содержит пустой путь. Но когда мы вызываем Path.toAbsolutePath(), он проверяет, больше ли длина пути больше нуля, в противном случае использует системное свойство user.dir и возвращает текущий путь.

Вот код для реализации файловой системы Unix: UnixPath.toAbsolutePath()


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

Также я бы предложил использовать File.separatorChar для независимого от платформы кода.

Path currentRelativePath = Paths.get("");
Path currentDir = currentRelativePath.toAbsolutePath(); // <-- Get the Path and use resolve on it.
String filename = "data" + File.separatorChar + "foo.txt";
Path filepath = currentDir.resolve(filename);

// "data/foo.txt"
System.out.println(filepath);

Вывод:

/Users/user/coding/data/foo.txt

Ответ 2

Paths#get(String first, String... more) состояния,

Преобразует строку пути или последовательность строк, которые при объединении образуют строку пути, в Path.

...

A Path, представляющий пустой путь, возвращается, если сначала пустое строка и многое другое не содержит никаких непустых строк.

Чтобы получить текущий каталог пользователя, вы можете просто использовать System.getProperty("user.dir").

Path path = Paths.get(System.getProperty("user.dir"), "abc.txt");
System.out.println(path);

Кроме того, метод get использует аргумент переменной длины String, который будет использоваться для предоставления последующих строк пути. Итак, чтобы создать Path для /test/inside/abc.txt, вы должны использовать его следующим образом,

Path path = Paths.get("/test", "inside", "abc.txt");

Ответ 3

Не определенный метод.

Если вы используете java 8 или выше, у вас есть 2 варианта:

a) Используйте java.util.StringJoiner

StringJoiner joiner = new StringJoiner(File.pathSeparator); //Separator
joiner.add("path1").add("path2");
String joinedString = joiner.toString();

b) Используйте String.join(File.pathSeparator, "path1", "path2");

Если вы используете java 7 или ниже, вы можете использовать библиотеку commons-lang из сообщества apache. Класс StringUtils имеет метод объединения строк с использованием разделителя.

c) StringUtils.join(new Object[] {"path1", "path2"}, File.pathSeparator);

A sidenote: вы можете использовать linux pathseparator "/" для Windows (просто помните, что абсолютные пути - это что-то вроде "/C:/mydir1/mydir2". Использование всегда "/" очень полезно, если вы используете такие протоколы, как файл://

Ответ 4

Самый простой способ:

Path filepath = Paths.get("foo", "bar");

Вы не должны писать Paths.get(""). Я удивлен, что работает вообще. Если вы хотите явно ссылаться на текущий каталог, используйте Paths.get(System.getProperty("user.dir")). Если вы хотите использовать домашний каталог пользователя, используйте Paths.get(System.getProperty("user.home")).

Вы также можете комбинировать подходы:

Path filepath = Paths.get(
    System.getProperty("user.home"), "data", "foo.txt");

Ответ 5

Самый надежный, независимый от платформы способ объединения путей в Java - это использовать Path::resolve (как указано в JavaDoc для Paths::get). Для массива произвольной длины строк, представляющих куски пути, они могут быть объединены вместе с использованием Java-потока:

private static final String[] pieces = {
    System.getProperty("user.dir"),
    "data",
    "foo.txt"};
public static void main (String[] args) {
    Path dest = Arrays.stream(pieces).reduce(
    /* identity    */ Paths.get(""),
    /* accumulator */ Path::resolve,
    /* combiner    */ Path::resolve);
    System.out.println(dest);
}