API Jalur NIO2 Java

1. Gambaran keseluruhan

Dalam artikel ini, kita akan belajar bagaimana menggunakan Path Path I / O (NIO2) baru di Java.

The Path API dalam NIO2 merupakan salah satu bidang fungsi baru utama yang dihantar dengan Java 7 dan khususnya subset API sistem fail baru bersama API fail.

2. Persediaan

Sokongan NIO2 digabungkan dalam pakej java.nio.file . Oleh itu, menyiapkan projek anda untuk menggunakan API Path hanyalah masalah mengimport semua dalam pakej ini:

import java.nio.file.*;

Oleh kerana sampel kod dalam artikel ini mungkin akan berjalan di persekitaran yang berbeza, mari kita menangani direktori utama pengguna:

private static String HOME = System.getProperty("user.home");

Pemboleh ubah ini akan menunjukkan lokasi yang sah di mana-mana persekitaran.

The Paths kelas adalah pintu masuk utama untuk semua operasi yang melibatkan laluan sistem fail. Ini membolehkan kita membuat dan memanipulasi jalan ke fail dan direktori.

Perlu diberi perhatian adalah bahawa operasi jalan terutamanya bersifat sintaksis; mereka tidak berpengaruh pada sistem fail yang mendasari dan juga sistem fail tidak mempengaruhi sama ada mereka berjaya atau gagal. Ini bermaksud bahawa melewati jalan yang tidak ada sebagai parameter operasi jalan tidak ada kaitannya sama ada ia berjaya atau gagal.

3. Operasi Laluan

Di bahagian ini, kami akan memperkenalkan sintaks utama yang digunakan dalam operasi jalan. Seperti namanya, kelas Path adalah representasi program dari jalan dalam sistem fail.

A Path objek mengandungi nama fail dan direktori senarai yang digunakan untuk membina jalan dan digunakan untuk memeriksa, mengesan, dan memanipulasi fail.

Kelas penolong, java.nio.file.Paths (dalam bentuk jamak) adalah cara formal untuk membuat objek Path . Ia mempunyai dua kaedah statik untuk membuat Path dari rentetan path:

Path path = Paths.get("path string");

Sama ada kita menggunakan garis depan atau garis miring terbalik dalam String, tidak masalah, API menyelesaikan parameter ini mengikut keperluan sistem fail yang mendasari.

Dan dari objek java.net.URI :

Path path = Paths.get(URI object);

Kita sekarang boleh maju dan melihatnya dalam tindakan.

4. Membuat Jalan

Untuk membuat objek Path dari rentetan path:

@Test public void givenPathString_whenCreatesPathObject_thenCorrect() { Path p = Paths.get("/articles/baeldung"); assertEquals("\\articles\\baeldung", p.toString()); }

The get API boleh mengambil hujah-hujah parameter pembolehubah bahagian rentetan jalan (dalam kes ini, artikel dan baeldung ) sebagai tambahan kepada bahagian pertama (dalam kes ini, artikel ).

Sekiranya kami menyediakan bahagian-bahagian ini dan bukannya rentetan jalur yang lengkap, ia akan digunakan untuk membina objek Path, kami tidak perlu memasukkan pemisah nama (garis miring) di bahagian argumen pemboleh ubah:

@Test public void givenPathParts_whenCreatesPathObject_thenCorrect() { Path p = Paths.get("/articles", "baeldung"); assertEquals("\\articles\\baeldung", p.toString()); }

5. Mengambil Maklumat Laluan

Anda boleh memikirkan objek Path sebagai elemen nama sebagai urutan. String jalan seperti E: \ baeldung \ artikel \ java terdiri daripada tiga elemen nama iaitu baeldung , artikel , dan java . Elemen tertinggi dalam struktur direktori akan berada di indeks 0, dalam hal ini adalah baeldung .

Elemen terendah dalam struktur direktori akan berada di indeks [n-1] , di mana n adalah bilangan elemen nama di jalan. Elemen terendah ini dipanggil nama fail tanpa mengira ia adalah fail sebenar atau tidak:

@Test public void givenPath_whenRetrievesFileName_thenCorrect() { Path p = Paths.get("/articles/baeldung/logs"); Path fileName = p.getFileName(); assertEquals("logs", fileName.toString()); }

Kaedah tersedia untuk mendapatkan elemen individu mengikut indeks:

@Test public void givenPath_whenRetrievesNameByIndex_thenCorrect() { Path p = Paths.get("/articles/baeldung/logs"); Path name0 = getName(0); Path name1 = getName(1); Path name2 = getName(2); assertEquals("articles", name0.toString()); assertEquals("baeldung", name1.toString()); assertEquals("logs", name2.toString()); }

atau sub-urutan jalan yang menggunakan julat indeks ini:

@Test public void givenPath_whenCanRetrieveSubsequenceByIndex_thenCorrect() { Path p = Paths.get("/articles/baeldung/logs"); Path subPath1 = p.subpath(0,1); Path subPath2 = p.subpath(0,2); assertEquals("articles", subPath1.toString()); assertEquals("articles\\baeldung", subPath2.toString()); assertEquals("articles\\baeldung\\logs", p.subpath(0, 3).toString()); assertEquals("baeldung", p.subpath(1, 2).toString()); assertEquals("baeldung\\logs", p.subpath(1, 3).toString()); assertEquals("logs", p.subpath(2, 3).toString()); }

Setiap jalan dikaitkan dengan jalan induk atau nol jika jalan tersebut tidak mempunyai ibu bapa. Induk objek jalan terdiri daripada komponen akar jalan, jika ada, dan setiap elemen di jalan kecuali untuk nama fail. Sebagai contoh, jalan induk / a / b / c adalah / a / b dan jalan dari / a adalah nol:

@Test public void givenPath_whenRetrievesParent_thenCorrect() { Path p1 = Paths.get("/articles/baeldung/logs"); Path p2 = Paths.get("/articles/baeldung"); Path p3 = Paths.get("/articles"); Path p4 = Paths.get("/"); Path parent1 = p1.getParent(); Path parent2 = p2.getParent(); Path parent3 = p3.getParent(); Path parent4 = p4.getParenth(); assertEquals("\\articles\\baeldung", parent1.toString()); assertEquals("\\articles", parent2.toString()); assertEquals("\\", parent3.toString()); assertEquals(null, parent4); }

Kita juga boleh mendapatkan elemen akar jalan:

@Test public void givenPath_whenRetrievesRoot_thenCorrect() { Path p1 = Paths.get("/articles/baeldung/logs"); Path p2 = Paths.get("c:/articles/baeldung/logs"); Path root1 = p1.getRoot(); Path root2 = p2.getRoot(); assertEquals("\\", root1.toString()); assertEquals("c:\\", root2.toString()); }

6. Menormalkan Jalan

Banyak sistem fail menggunakan "." notasi untuk menunjukkan direktori semasa dan ".." untuk menunjukkan direktori induk. Anda mungkin mempunyai situasi di mana jalan mengandungi maklumat direktori yang berlebihan.

Sebagai contoh, pertimbangkan rentetan jalur berikut:

/baeldung/./articles /baeldung/authors/../articles /baeldung/articles

They all resolve to the same location /baeldung/articles. The first two have redundancies while the last one does not.

Normalizing a path involves removing redundancies in it. The Path.normalize() operation is provided for this purpose.

This example should now be self-explanatory:

@Test public void givenPath_whenRemovesRedundancies_thenCorrect1() { Path p = Paths.get("/home/./baeldung/articles"); Path cleanPath = p.normalize(); assertEquals("\\home\\baeldung\\articles", cleanPath.toString()); }

This one too:

@Test public void givenPath_whenRemovesRedundancies_thenCorrect2() { Path p = Paths.get("/home/baeldung/../articles"); Path cleanPath = p.normalize(); assertEquals("\\home\\articles", cleanPath.toString()); }

7. Path Conversion

There are operations to convert a path to a chosen presentation format. To convert any path into a string that can be opened from the browser, we use the toUri method:

@Test public void givenPath_whenConvertsToBrowseablePath_thenCorrect() { Path p = Paths.get("/home/baeldung/articles.html"); URI uri = p.toUri(); assertEquals( "file:///E:/home/baeldung/articles.html", uri.toString()); }

We can also convert a path to its absolute representation. The toAbsolutePath method resolves a path against a file system default directory:

@Test public void givenPath_whenConvertsToAbsolutePath_thenCorrect() { Path p = Paths.get("/home/baeldung/articles.html"); Path absPath = p.toAbsolutePath(); assertEquals( "E:\\home\\baeldung\\articles.html", absPath.toString()); }

However, when the path to be resolved is detected to be already absolute, the method returns it as is:

@Test public void givenAbsolutePath_whenRetainsAsAbsolute_thenCorrect() { Path p = Paths.get("E:\\home\\baeldung\\articles.html"); Path absPath = p.toAbsolutePath(); assertEquals( "E:\\home\\baeldung\\articles.html", absPath.toString()); }

We can also convert any path to its real equivalent by calling the toRealPath method. This method tries to resolve the path by mapping it's elements to actual directories and files in the file system.

Time to use the variable we created in the Setup section which points to logged-in user's home location in the file system:

@Test public void givenExistingPath_whenGetsRealPathToFile_thenCorrect() { Path p = Paths.get(HOME); Path realPath = p.toRealPath(); assertEquals(HOME, realPath.toString()); }

The above test does not really tell us much about the behavior of this operation. The most obvious result is that if the path does not exist in the file system, then the operation will throw an IOException, read on.

For the lack of a better way to drive this point home, just take a look at the next test, which attempts to convert an inexistent path to a real path:

@Test(expected = NoSuchFileException.class) public void givenInExistentPath_whenFailsToConvert_thenCorrect() { Path p = Paths.get("E:\\home\\baeldung\\articles.html"); p.toRealPath(); }

The test succeeds when we catch an IOException. The actual subclass of IOException that this operation throws is NoSuchFileException.

8. Joining Paths

Joining any two paths can be achieved using the resolve method.

Simply put, we can call the resolve method on any Path and pass in a partial path as the argument. That partial path is appended to the original path:

@Test public void givenTwoPaths_whenJoinsAndResolves_thenCorrect() { Path p = Paths.get("/baeldung/articles"); Path p2 = p.resolve("java"); assertEquals("\\baeldung\\articles\\java", p2.toString()); }

However, when the path string passed to the resolve method is not a partial path; most notably an absolute path, then the passed-in path is returned:

@Test public void givenAbsolutePath_whenResolutionRetainsIt_thenCorrect() { Path p = Paths.get("/baeldung/articles"); Path p2 = p.resolve("C:\\baeldung\\articles\java"); assertEquals("C:\\baeldung\\articles\\java", p2.toString()); }

The same thing happens with any path that has a root element. The path string “java” has no root element while the path string “/java” has a root element. Therefore, when you pass in a path with a root element, it is returned as is:

@Test public void givenPathWithRoot_whenResolutionRetainsIt_thenCorrect2() { Path p = Paths.get("/baeldung/articles"); Path p2 = p.resolve("/java"); assertEquals("\\java", p2.toString()); }

9. Relativizing Paths

The term relativizing simply means creating a direct path between two known paths. For instance, if we have a directory /baeldung and inside it, we have two other directories such that /baeldung/authors and /baeldung/articles are valid paths.

The path to articles relative to authors would be described as “move one level up in the directory hierarchy then into articles directory” or ..\articles:

@Test public void givenSiblingPaths_whenCreatesPathToOther_thenCorrect() { Path p1 = Paths.get("articles"); Path p2 = Paths.get("authors"); Path p1_rel_p2 = p1.relativize(p2); Path p2_rel_p1 = p2.relativize(p1); assertEquals("..\\authors", p1_rel_p2.toString()); assertEquals("..\\articles", p2_rel_p1.toString()); }

Assuming we move the articles directory to authors folder such that they are no longer siblings. The following relativizing operations involve creating a path between baeldung and articles and vice versa:

@Test public void givenNonSiblingPaths_whenCreatesPathToOther_thenCorrect() { Path p1 = Paths.get("/baeldung"); Path p2 = Paths.get("/baeldung/authors/articles"); Path p1_rel_p2 = p1.relativize(p2); Path p2_rel_p1 = p2.relativize(p1); assertEquals("authors\\articles", p1_rel_p2.toString()); assertEquals("..\\..", p2_rel_p1.toString()); }

10. Comparing Paths

The Path class has an intuitive implementation of the equals method which enables us to compare two paths for equality:

@Test public void givenTwoPaths_whenTestsEquality_thenCorrect() { Path p1 = Paths.get("/baeldung/articles"); Path p2 = Paths.get("/baeldung/articles"); Path p3 = Paths.get("/baeldung/authors"); assertTrue(p1.equals(p2)); assertFalse(p1.equals(p3)); }

You can also check if a path begins with a given string:

@Test public void givenPath_whenInspectsStart_thenCorrect() { Path p1 = Paths.get("/baeldung/articles"); assertTrue(p1.startsWith("/baeldung")); }

Or ends with some other string:

@Test public void givenPath_whenInspectsEnd_thenCorrect() { Path p1 = Paths.get("/baeldung/articles"); assertTrue(p1.endsWith("articles")); }

11. Conclusion

Dalam artikel ini, kami menunjukkan operasi Path di API sistem fail baru (NIO2) yang dikirim sebagai bagian dari Java 7 dan melihat sebagian besar dari mereka beraksi.

Contoh kod yang digunakan dalam artikel ini boleh didapati di projek Github artikel.