Liigu peamise sisu juurde

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:

FilePath / Files
Kasutuses alatesJava 1.0Java 7
Veateated ebaõnnestumiselTagastab false (vaikne)Visatakse erind
VaikekodeeringPlatvormi vaikimisiUTF-8
Voogude API tugiPuudubOlemas
Sümboolsed lingidPiiratud tugiTä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.