File klass
Sissejuhatus
Enne kui Java programm saab andmeid lugeda või kirjutada, peab tal olema viis viidata asukohale kettal.
java.io klassil olev File klass on seda eesmärki täitnud alates esimesest Java versioonist.
See esindab viidet failini või kataloogini ning pakub meetodeid failisüsteemi uurimiseks ja haldamiseks selles asukohas.
File klassi mõistmine on kasulik nii vanemate koodibaasidega töötamisel kui ka teekide kasutamisel, kus meetodid võivad endiselt võtta File objekti vastu parameetrina.
Kaasaegses Javas on võimalik kasutada võimekamat lahendust Path ja Files klasside näol, mida käsitletakse järgmises peatükis.
File objekti loomine
File objekti loomisel tuleb konstruktorile anda ette sõne, mis kirjeldab faili asukohta.
See ei loo faili kettale, vaid loob ainult Java objekti, mis esindab seda asukohta:
File file = new File("books.txt"); // relative to working directory
File absolute = new File("/home/user/books.txt"); // absolute path
File nested = new File("data/library/books.txt"); // nested path
Samuti on võimalik kasutada kahe argumendiga konstruktorit, kus esimene argument esindab parent viita (alatihti kausta, kus fail peaks olema) ning teine faili iseennast:
File dir = new File("data");
File file = new File(dir, "books.txt"); // data/books.txt
Olemasolu ja tüübi kontrollimine
File file = new File("books.txt");
boolean exists = file.exists(); // true if the path exists (file or directory)
boolean isFile = file.isFile(); // true if it exists and is a regular file
boolean isDirectory = file.isDirectory(); // true if it exists and is a directory
Failiomadused
File file = new File("books.txt");
String name = file.getName(); // "books.txt"
String path = file.getPath(); // "books.txt" (as given to constructor)
String absPath = file.getAbsolutePath(); // full path from filesystem root
File parent = file.getParentFile(); // File representing the parent directory
long size = file.length(); // size in bytes (0 if file does not exist)
boolean canRead = file.canRead();
boolean canWrite = file.canWrite();
Failide ja kataloogide loomine
File file = new File("books.txt");
boolean created = file.createNewFile(); // creates the file; returns false if it already exists
// throws IOException if creation fails
File dir = new File("data/library");
boolean madeDir = dir.mkdir(); // creates one directory; parent must already exist
boolean madeDirs = dir.mkdirs(); // creates the full path including any missing parents
Levinud muster on fail luua ainult siis, kui seda veel ei eksisteeri:
File file = new File("books.txt");
if (!file.exists()) {
file.createNewFile();
}
Failide kustutamine
File file = new File("books.txt");
boolean deleted = file.delete(); // returns false if deletion failed or file did not exist
Erinevalt Files.delete() meetodist, File.delete() ei viska erindit, kui faili kustutamine ebaõnnestus.
Selle asemel tagastatakse ainult false.
See tähendab, et ebaõnnestunud operatsioonid võivad märkamata jääda, kui delete() meetodi vastust ei kontrollita.
Kataloogi sisu kuvamine
File dir = new File("data");
String[] names = dir.list(); // array of names (strings)
File[] files = dir.listFiles(); // array of File objects
Mõlemad meetodid tagastavad null, kui path ei viita kataloogile või seda ei eksisteeri ehk null-väärtuse kontrolli teostamine on siin kohal tähtis:
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
System.out.println(f.getName());
}
}
Failist lugemine ja faili kirjutamine
File ise ei loe ega kirjuta sisu - see esindab ainult asukohta.
Lugemiseks või kirjutamiseks antakse File objekt edasi lugejale või kirjutajale:
File file = new File("books.txt");
// Reading
BufferedReader reader = new BufferedReader(new FileReader(file));
// Writing
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
BufferedWriter appending = new BufferedWriter(new FileWriter(file, true)); // append mode
FileReader ja FileWriter kasutavad platvormi vaikimisi märgikodeeringut, mis võib erinevates süsteemides anda erinevaid tulemusi.
Hea tava on kodeering selgesõnaliselt ära määrata:
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
Lugejad ja kirjutajad tuleb alati pärast kasutamist sulgeda. Üks viis kuidas seda tehakse on try-with-resources-i kasutades, mis tagab, et sulgemine toimub ka erindi tekkimisel:
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Could not read file: " + e.getMessage());
}
Teisendamine File ja Path vahel
Kuna paljud kaasaegsed API-d kasutavad Path-i, samas kui vanemad teegid kasutavad endiselt File-i, pakub Java otsest teisendust mõlemas suunas:
// File to Path
File file = new File("books.txt");
Path path = file.toPath();
// Path to File
Path path = Path.of("books.txt");
File file = path.toFile();
See teeb lihtsaks kaasaegsete API-de kasutamise ka siis, kui mõni vanem teek annab sulle File objekti.
File vs Path
File on endiselt laialt kasutusel Java koodibaasides ja teekides, kuid sellel on mitmeid piiranguid, mille lahendamiseks loodi uuem Path/Files API:
File | Path / Files | |
|---|---|---|
| Kasutuses alates | Java 1.0 | Java 7 |
| Veateated ebaõnnestumisel | Tagastab false (vaikne) | Visatakse erind |
| Vaikekodeering | Platvormi vaikimisi | UTF-8 |
| Voogude API tugi | Puudub | Olemas |
| Sümboolsed lingid | Piiratud tugi | Täielik tugi |
Uue koodi puhul on eelistatud Path ja Files kasutamine.
File klassi tasub siiski tunda, et mõista olemasolevat koodi ning vajadusel teisendada File objektid Path-iks.