Bevezetés a Java NIO2 File API-ba
1. Áttekintés
Ebben a cikkben a Java Platform új I / O API-jára fogunk összpontosítani - NIO2 - alapvető fájlkezelés.
A NIO2 fájl API-k alkotják a Java 7 egyik legfontosabb új funkcionális területét, amelyet a Java 7-el együtt szállítottak, nevezetesen az új fájlrendszer API részhalmazát a Path API-k mellett.
2. Beállítás
A projekt beállítása a File API-k használatára csak az importálás kérdése:
import java.nio.file. *;
Mivel az ebben a cikkben szereplő kódminták valószínűleg különböző környezetekben fognak futni, szerezzünk egy kezelési lehetőséget a felhasználó saját könyvtárában, amely minden operációs rendszerre érvényes lesz:
privát statikus karakterlánc HOME = System.getProperty ("user.home");
A Fájlok osztály az egyik elsődleges belépési pont a java.nio.file csomag. Ez az osztály gazdag API-kat kínál a fájlok és könyvtárak olvasására, írására és kezelésére. A Fájlok osztályos módszerek működnek az Pálya tárgyakat.
3. Fájl vagy könyvtár ellenőrzése
Van egy Pálya egy fájlt vagy könyvtárat reprezentáló példány a fájlrendszerben. Függetlenül attól, hogy létezik-e az a fájl vagy könyvtár, amelyre mutat, vagy sem, egy fájlművelettel meg lehet erősíteni.
Az egyszerűség kedvéért, valahányszor ezt a kifejezést használjuk fájl, mind a fájlokra, mind a könyvtárakra hivatkozunk, hacsak kifejezetten másként nem jelezzük.
A fájl létezésének ellenőrzéséhez a létezik API:
@Test public void givenExistentPath_whenConfirmsFileExists_thenCorrect () {Path p = Paths.get (HOME); assertTrue (Fájlok.létezik (p)); }
A fájl nem létezésének ellenőrzéséhez a nem létezik API:
@Test public void givenNonexistentPath_whenConfirmsFileNotExists_thenCorrect () {Path p = Paths.get (HOME + "/inexistent_file.txt"); assertTrue (Fájlok.notExists (p)); }
Azt is ellenőrizhetjük, hogy egy fájl szokásos fájl-e myfile.txt vagy csak könyvtár, akkor a isRegularFile API:
@Test public void givenDirPath_whenConfirmsNotRegularFile_thenCorrect () {Path p = Paths.get (HOME); assertFalse (Files.isRegularFile (p)); }
A fájlengedélyek ellenőrzésére statikus módszerek is léteznek. Annak ellenőrzésére, hogy egy fájl olvasható-e, a isolvasható API:
@Test public void givenExistentDirPath_whenConfirmsReadable_thenCorrect () {Path p = Paths.get (HOME); assertTrue (Files.isReadable (p)); }
Annak ellenőrzésére, hogy írható-e, a írható API:
@Test public void givenExistentDirPath_whenConfirmsWritable_thenCorrect () {Path p = Paths.get (HOME); assertTrue (Files.isWritable (p)); }
Hasonlóképpen ellenőrizze, hogy végrehajtható-e:
@Test public void givenExistentDirPath_whenConfirmsExecutable_thenCorrect () {Path p = Paths.get (HOME); assertTrue (Files.isExecutable (p)); }
Ha két útvonalunk van, ellenőrizhetjük, hogy mindkettő ugyanarra a fájlra mutat-e az alapul szolgáló fájlrendszeren:
@Test public void givenSameFilePaths_whenConfirmsIsSame_thenCorrect () {Path p1 = Paths.get (HOME); P2 útvonal = Paths.get (HOME); assertTrue (Files.isSameFile (p1, p2)); }
4. Fájlok létrehozása
A fájlrendszer API egysoros műveleteket biztosít a fájlok létrehozásához. Rendes fájl létrehozásához a createFile API és adja át a Pálya a létrehozni kívánt fájlt képviselő objektum.
Az útvonalban található összes névelemnek léteznie kell, a fájlnéven kívül, különben egy IOException:
@Test public void givenFilePath_whenCreatesNewFile_thenCorrect () {String fileName = "myfile_" + UUID.randomUUID (). ToString () + ".txt"; Path p = Paths.get (HOME + "/" + fájlnév); assertFalse (Fájlok.létezik (p)); Files.createFile (p); assertTrue (Fájlok.létezik (p)); }
A fenti tesztben, amikor először ellenőrizzük az útvonalat, akkor az nem létezik, majd a createFile művelet létezik.
Könyvtár létrehozásához a createDirectory API:
@Test public void givenDirPath_whenCreatesNewDir_thenCorrect () {String dirName = "myDir_" + UUID.randomUUID (). ToString (); Path p = Paths.get (HOME + "/" + dirName); assertFalse (Fájlok.létezik (p)); Files.createDirectory (p); assertTrue (Fájlok.létezik (p)); assertFalse (Files.isRegularFile (p)); assertTrue (Fájlok.isDirectory (p)); }
Ehhez a művelethez meg kell adni az útvonalban található összes névelemet, ha nem, akkor kapunk egy IOException:
@Test (várható = NoSuchFileException.class) public void givenDirPath_whenFailsToCreateRecursively_thenCorrect () {String dirName = "myDir_" + UUID.randomUUID (). ToString () + "/ alkönyvtár"; Path p = Paths.get (HOME + "/" + dirName); assertFalse (Fájlok.létezik (p)); Files.createDirectory (p); }
Ha azonban egyetlen hívással szeretnénk létrehozni a könyvtárak hierarchiáját, akkor a createDirectories módszer. Az előző művelettel ellentétben, amikor az útvonalon hiányzó névelemekkel találkozik, nem dob egy IOException, rekurzív módon létrehozza őket az utolsó elemig:
@Test public void givenDirPath_whenCreatesRecursively_thenCorrect () {Útvonal dir = Paths.get (HOME + "/ myDir_" + UUID.randomUUID (). ToString ()); Útvonal alkönyvtár = dir.resolve ("alkönyvtár"); assertFalse (Fájlok.létezik (dir)); assertFalse (Files.exists (alkönyvtár)); Files.createDirectories (alkönyvtár); assertTrue (Fájlok.létezik (dir)); assertTrue (Fájlok.létezik (alkönyvtár)); }
5. Ideiglenes fájlok létrehozása
Sok alkalmazás futás közben ideiglenes fájlok nyomvonalát hozza létre a fájlrendszerben. Ennek eredményeként a legtöbb fájlrendszer rendelkezik külön könyvtárral az ilyen alkalmazások által létrehozott ideiglenes fájlok tárolására.
Az új fájlrendszer API speciális műveleteket biztosít erre a célra. A createTempFile Az API végrehajtja ezt a műveletet. Ehhez elérési út objektum, fájl előtag és fájl utótag szükséges:
@Test public void givenFilePath_whenCreatesTempFile_thenCorrect () {String prefix = "log_"; Karakterlánc utótag = ".txt"; Path p = Paths.get (HOME + "/"); Files.createTempFile (p, előtag, utótag); assertTrue (Fájlok.létezik (p)); }
Ezek a paraméterek elegendőek a műveletet igénylő követelményekhez. Ha azonban meg kell adnia a fájl meghatározott attribútumait, akkor van egy negyedik változó argumentum paraméter.
A fenti teszt egy ideiglenes fájlt hoz létre a ITTHON könyvtár, a függőleges és a mellékelt előtag- és utótag-karakterláncok függőben vannak. Végül egy ilyen fájlnévvel találkozunk log_8821081429012075286.txt. A hosszú numerikus karakterláncot a rendszer generálja.
Ha azonban nem adunk meg előtagot és utótagot, akkor a fájlnév csak a hosszú numerikus karakterláncot és egy alapértelmezettet tartalmaz .tmp kiterjesztés:
@Test public void givenPath_whenCreatesTempFileWithDefaults_thenCorrect () {Path p = Paths.get (HOME + "/"); Files.createTempFile (p, null, null); assertTrue (Fájlok.létezik (p)); }
A fenti művelet egy ilyen nevű fájlt hoz létre 8600179353689423985.tmp.
Végül, ha nem adunk meg sem utat, sem előtagot, sem utótagot, akkor a művelet az alapértelmezéseket használja. A létrehozott fájl alapértelmezett helye a fájlrendszer által biztosított ideiglenes fájl könyvtár lesz:
@Test public void givenNoFilePath_whenCreatesTempFileInTempDir_thenCorrect () {Path p = Files.createTempFile (null, null); assertTrue (Fájlok.létezik (p)); }
Windows rendszeren ez alapértelmezés szerint valami hasonló lesz C: \ Users \ user \ AppData \ Local \ Temp \ 6100927974988978748.tmp.
A fenti műveletek alkalmazhatók könyvtárak létrehozására, nem pedig normál fájlok használatával createTempDirectory ahelyett createTempFile.
6. Fájl törlése
Fájl törléséhez a töröl API. Az egyértelműség kedvéért a következő teszt először biztosítja, hogy a fájl még nem létezik, majd létrehozza, megerősíti, hogy létezik, végül törli, és megerősíti, hogy már nem létezik:
@Test public void givenPath_whenDeletes_thenCorrect () {Path p = Paths.get (HOME + "/fileToDelete.txt"); assertFalse (Fájlok.létezik (p)); Files.createFile (p); assertTrue (Fájlok.létezik (p)); Files.delete (p); assertFalse (Fájlok.létezik (p)); }
Ha azonban egy fájl nem létezik a fájlrendszerben, akkor a törlési művelet sikertelen lesz egy IOException:
@Test (várható = NoSuchFileException.class) public void givenInexistentFile_whenDeleteFails_thenCorrect () {Path p = Paths.get (HOME + "/inexistentFile.txt"); assertFalse (Fájlok.létezik (p)); Files.delete (p); }
Használatával elkerülhetjük ezt a forgatókönyvet deleteIfExists amelyek csendesen kudarcot vallanak abban az esetben, ha a fájl nem létezik. Ez akkor fontos, ha több szál végzi ezt a műveletet, és nem akarunk hibaüzenetet egyszerűen azért, mert egy szál korábban hajtotta végre a műveletet, mint a jelenlegi sikertelen szál:
@Test public void givenInexistentFile_whenDeleteIfExistsWorks_thenCorrect () {Path p = Paths.get (HOME + "/inexistentFile.txt"); assertFalse (Fájlok.létezik (p)); Files.deleteIfExists (p); }
A könyvtárakkal és nem a szokásos fájlokkal való foglalkozás során emlékeznünk kell arra, hogy a törlési művelet alapértelmezés szerint nem működik rekurzív módon. Tehát ha egy könyvtár nem üres, akkor egy IOException:
@Test (várható = DirectoryNotEmptyException.class) public void givenPath_whenFailsToDeleteNonEmptyDir_thenCorrect () {Path dir = Paths.get (HOME + "/ emptyDir" + UUID.randomUUID (). ToString ()); Files.createDirectory (dir); assertTrue (Fájlok.létezik (dir)); Útvonal fájl = dir.resolve ("file.txt"); Files.createFile (fájl); Files.delete (dir); assertTrue (Fájlok.létezik (dir)); }
7. Fájlok másolása
A fájlt vagy könyvtárat a másolat API:
@Test public void givenFilePath_whenCopiesToNewLocation_thenCorrect () {Dirath path = Paths.get (HOME + "/ firstdir_" + UUID.randomUUID (). ToString ()); Útvonal dir2 = Paths.get (HOME + "/ otherdir_" + UUID.randomUUID (). ToString ()); Files.createDirectory (dir1); Files.createDirectory (dir2); Útvonal fájl1 = dir1.resolve ("filetocopy.txt"); Útvonalfájl2 = dir2.resolve ("filetocopy.txt"); Files.createFile (fájl1); assertTrue (Fájlok.létezik (fájl1)); assertFalse (Fájlok.létezik (fájl2)); Files.copy (fájl1, fájl2); assertTrue (Fájlok.létezik (fájl2)); }
A másolás sikertelen, ha a célfájl létezik, hacsak a REPLACE_EXISTING opció van megadva:
@Test (várható = FileAlreadyExistsException.class) public void givenPath_whenCopyFailsDueToExistingFile_thenCorrect () {Útvonal dir1 = Paths.get (HOME + "/ firstdir_" + UUID.randomUUID (). ToString ()); Útvonal dir2 = Paths.get (HOME + "/ otherdir_" + UUID.randomUUID (). ToString ()); Files.createDirectory (dir1); Files.createDirectory (dir2); Útvonal fájl1 = dir1.resolve ("filetocopy.txt"); Útvonalfájl2 = dir2.resolve ("filetocopy.txt"); Files.createFile (fájl1); Files.createFile (fájl2); assertTrue (Fájlok.létezik (fájl1)); assertTrue (Fájlok.létezik (fájl2)); Files.copy (fájl1, fájl2); Files.copy (fájl1, fájl2, StandardCopyOption.REPLACE_EXISTING); }
Könyvtárak másolásakor azonban a tartalom nem kerül rekurzív módon másolásra. Ez azt jelenti, hogy ha / baeldung tartalmazza /articles.db és /authors.db fájlok, másolás / baeldung új helyre egy üres könyvtárat hoz létre.
8. Fájlok mozgatása
A fájlt vagy könyvtárat áthelyezheti a mozog API. A legtöbb szempontból hasonló a másolat művelet. Ha a másolási művelet analóg a másolás és beillesztés akkor a GUI alapú rendszerekben való működés mozog analóg a kivágás és beillesztés művelet:
@Test public void givenFilePath_whenMovesToNewLocation_thenCorrect () {Dirath path1 = Paths.get (HOME + "/ firstdir_" + UUID.randomUUID (). ToString ()); Útvonal dir2 = Paths.get (HOME + "/ otherdir_" + UUID.randomUUID (). ToString ()); Files.createDirectory (dir1); Files.createDirectory (dir2); Útvonal fájl1 = dir1.resolve ("filetocopy.txt"); Útvonalfájl2 = dir2.resolve ("filetocopy.txt"); Files.createFile (fájl1); assertTrue (Fájlok.létezik (fájl1)); assertFalse (Fájlok.létezik (fájl2)); Files.move (fájl1, fájl2); assertTrue (Fájlok.létezik (fájl2)); assertFalse (Fájlok.létezik (fájl1)); }
A mozog művelet sikertelen, ha a célfájl létezik, hacsak a REPLACE_EXISTING opció pontosan meg van adva, mint mi a másolat művelet:
@Test (várható = FileAlreadyExistsException.class) public void givenFilePath_whenMoveFailsDueToExistingFile_thenCorrect () {Útvonal dir1 = Paths.get (HOME + "/ firstdir_" + UUID.randomUUID (). ToString ()); Útvonal dir2 = Paths.get (HOME + "/ otherdir_" + UUID.randomUUID (). ToString ()); Files.createDirectory (dir1); Files.createDirectory (dir2); Útvonal fájl1 = dir1.resolve ("filetocopy.txt"); Útvonalfájl2 = dir2.resolve ("filetocopy.txt"); Files.createFile (fájl1); Files.createFile (fájl2); assertTrue (Fájlok.létezik (fájl1)); assertTrue (Fájlok.létezik (fájl2)); Files.move (fájl1, fájl2); Files.move (fájl1, fájl2, StandardCopyOption.REPLACE_EXISTING); assertTrue (Fájlok.létezik (fájl2)); assertFalse (Fájlok.létezik (fájl1)); }
9. Következtetés
Ebben a cikkben megismerkedtünk a fájl API-kkal az új fájlrendszer API-ban (NIO2), amelyet a Java 7 részeként szállítottak le, és a fontos fájlműveletek többségét működés közben látták.
Az ebben a cikkben használt kódminták a cikk Github projektjében találhatók.