Объединение путей в 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
.
Что я ошибаюсь?
Ответы
Ответ 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);
}