Jalur penggabungan di Jawa


99

Di Pythonsaya bisa bergabung dengan dua jalur dengan os.path.join:

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

Saya mencoba untuk mencapai hal yang sama di Java, tanpa khawatir jika OSadalah Unix, Solarisatau 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);

}

Saya berharap itu Path.resolve( )akan bergabung /home/user/testdengan direktori saya saat ini dengan data/foo.txtmembuat /home/user/test/data/foo.txt. Apa yang salah?


1
ini mungkin sesuatu yang tidak saya lihat. Jalur Anda saat ini adalah "". Jalur kedua Anda adalah "data / foo.txt". Mungkin masalah Anda adalah Anda tampaknya mencetak objek Path alih-alihfilepath.toString()
cjds

2
Gunakannew File(parent, child)
saka1029

Jawaban:


99

Meskipun solusi asli untuk mendapatkan direktori saat ini menggunakan empty Stringkarya. Tetapi disarankan untuk menggunakan user.dirproperti untuk direktori saat ini dan user.homeuntuk direktori home.

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

keluaran:

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

Dari kelas Dokumentasi Path Java :

Jalur dianggap jalur kosong jika hanya terdiri dari satu elemen nama yaitu empty. Mengakses file menggunakan salah empty path is equivalent to accessing the default directorysatu dari sistem file.


Mengapa Paths.get("").toAbsolutePath()berhasil

Ketika string kosong dilewatkan ke Paths.get(""), Pathobjek yang dikembalikan berisi jalur kosong. Tetapi ketika kita memanggil Path.toAbsolutePath(), ia memeriksa apakah panjang jalur lebih besar dari nol, jika tidak, ia menggunakan user.dirproperti sistem dan mengembalikan jalur saat ini.

Berikut adalah kode untuk implementasi sistem file Unix: UnixPath.toAbsolutePath ()


Pada dasarnya Anda perlu membuat Pathinstance lagi setelah Anda menyelesaikan jalur direktori saat ini.

Juga saya sarankan menggunakan File.separatorCharuntuk kode platform independen.

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

Keluaran:

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

Bukan saya, mungkin seseorang berpikir mengerjakan string dan separatorCharlebih rendah dari beberapa "abstraksi tingkat tinggi", sesuatu yang terlihat sepertiPathBuilder(currentRelativePath).append("data").append("foo.txt")
jingyu9575

22

Paths#get(String first, String... more) menyatakan,

Mengonversi string jalur, atau urutan string yang ketika digabungkan membentuk string jalur, menjadi Path.

...

Sebuah Pathmewakili jalur kosong dikembalikan jika first adalah string kosong dan lebih tidak berisi string yang tidak kosong.

Untuk mendapatkan direktori pengguna saat ini, Anda cukup menggunakan System.getProperty("user.dir").

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

Selain itu, getmetode menggunakan argumen panjang variabel dari String, yang akan digunakan untuk memberikan string path berikutnya. Jadi, untuk membuat Pathuntuk /test/inside/abc.txtAnda harus menggunakannya dengan cara berikut,

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

11

Bukan metode khusus.

Jika Anda menggunakan java 8 atau lebih baik, Anda memiliki 2 opsi:

a) Gunakan java.util.StringJoiner

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

b) Gunakan String.join(File.pathSeparator, "path1", "path2");

Jika Anda menggunakan java 7 atau yang lebih rendah, Anda dapat menggunakan library commons-lang dari apache commons. Kelas StringUtils memiliki metode untuk menggabungkan string menggunakan pemisah.

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

Catatan samping: Anda dapat menggunakan pemisah jalur linux "/" untuk windows (Ingatlah bahwa jalur absolut adalah seperti "/ C: / mydir1 / mydir2". Selalu menggunakan "/" sangat berguna jika Anda menggunakan protokol seperti file: //


StringJoiner mengembalikan saya/home/user/test:foo.txt
cybertextron

Opsi yang Anda ketahui bukan satu-satunya yang ada. Seseorang bisa menggunakan StringBuilder sebagai ganti joiner, misalnya. Dan nyatanya, implementasi Anda berdasarkan Strings daripada files / paths cukup naif dan akan menyebabkan masalah di banyak skenario.
XenoRo

2
File.separatorbekerja untuk saya alih-alihFile.pathSeparator
Evan Siroky

gunakan Pathes.get ("path1", "path2"). toAbsolutePath (). toString ()
Erdinc Ay

5

Cara paling dasar adalah:

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

Anda tidak boleh menulis Paths.get(""). Saya terkejut itu berhasil sama sekali. Jika Anda ingin merujuk ke direktori saat ini secara eksplisit, gunakan Paths.get(System.getProperty("user.dir")). Jika Anda menginginkan direktori home pengguna, gunakan Paths.get(System.getProperty("user.home")).

Anda juga dapat menggabungkan pendekatan:

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

1

Cara paling andal dan tidak bergantung platform untuk menggabungkan jalur di Java adalah dengan menggunakan Path::resolve(seperti yang disebutkan di JavaDoc untuk Paths::get). Untuk larik String dengan panjang arbitrer yang mewakili bagian dari jalur, ini dapat digabungkan bersama menggunakan Java Stream:

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

1

Anda bisa melakukan seperti

// /root
Path rootPath = Paths.get("/root");
// /root/temp
Path temPath = rootPath.resolve("temp");

Sebuah posting rinci yang bagus ada di sini Path Sample Usecase

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.