קבצים
מבוא
עבודה עם קבצים היא חלק בסיסי מכל שפת תכנות. ב-Java יש כמה דרכים לעבוד עם קבצים, מהישנות והמסורבלות עד החדשות והפשוטות.
ייבואים נפוצים
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
המחלקה File
File file = new File("data.txt");
file.exists(); // האם קיים?
file.length(); // גודל בבייטים
file.isFile(); // האם קובץ?
file.isDirectory(); // האם תיקייה?
file.getName(); // שם הקובץ
file.getAbsolutePath(); // נתיב מלא
file.delete(); // מחיקה
file.createNewFile(); // יצירה
שימו לב: File לא מייצגת את תוכן הקובץ - רק את הנתיב והמטא-דאטה.
Path ו-Files (מודרני)
מ-Java 7, החבילה java.nio.file הציעה API חדש ונוח יותר:
Path path = Paths.get("data.txt");
או דרך Path.of מ-Java 11:
Path path = Path.of("data.txt");
קריאה מקובץ
הדרך המודרנית - קריאה כמחרוזת
import java.nio.file.Files;
import java.nio.file.Path;
String content = Files.readString(Path.of("data.txt"));
System.out.println(content);
קריאה לפי שורות
List<String> lines = Files.readAllLines(Path.of("data.txt"));
for (String line : lines) {
System.out.println(line);
}
הדרך הקלאסית - עם Scanner
import java.io.File;
import java.util.Scanner;
Scanner scanner = new Scanner(new File("data.txt"));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
scanner.close();
הדרך הקלאסית - BufferedReader
לקבצים גדולים, יעיל יותר:
import java.io.BufferedReader;
import java.io.FileReader;
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
כתיבה לקובץ
כמחרוזת
Files.writeString(Path.of("output.txt"), "שלום עולם");
כרשימת שורות
List<String> lines = List.of("שורה 1", "שורה 2", "שורה 3");
Files.write(Path.of("output.txt"), lines);
עם PrintWriter
import java.io.PrintWriter;
try (PrintWriter writer = new PrintWriter("output.txt")) {
writer.println("שורה ראשונה");
writer.println("שורה שנייה");
writer.printf("מספר: %d%n", 42);
}
הוספה (append) במקום דריסה
import java.io.FileWriter;
try (FileWriter fw = new FileWriter("output.txt", true)) {
fw.write("שורה חדשה\n");
}
הפרמטר השני true אומר "append".
try-with-resources
בכל עבודה עם קבצים - חובה לסגור את הזרם. try-with-resources עושה את זה אוטומטית:
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
// שימוש ב-br
}
// br סגור אוטומטית, גם אם היתה חריגה
זה הרבה יותר בטוח מ-try-finally ידני.
עבודה עם תיקיות
Path dir = Path.of("myFolder");
// יצירת תיקייה
Files.createDirectory(dir);
// יצירת תיקייה כולל אב-תיקיות
Files.createDirectories(Path.of("a/b/c"));
// רשימת קבצים בתיקייה
try (var stream = Files.list(dir)) {
stream.forEach(System.out::println);
}
// האם קיים?
Files.exists(dir);
// מחיקה
Files.delete(dir);
חריגות
רוב פעולות I/O זורקות IOException. או שתתפוס אותה ב-try/catch, או שתכריז
שהפונקציה זורקת אותה:
public static void readFile() throws IOException {
String content = Files.readString(Path.of("data.txt"));
System.out.println(content);
}
או:
public static void readFile() {
try {
String content = Files.readString(Path.of("data.txt"));
System.out.println(content);
} catch (IOException e) {
System.err.println("שגיאה: " + e.getMessage());
}
}
נתיבים יחסיים מול מוחלטים
Path relative = Path.of("data.txt"); // יחסי לתיקיית העבודה
Path absolute = Path.of("C:/Users/nafta/data.txt"); // מוחלט
תיקיית העבודה היא בדרך כלל המקום שממנו הרצת את התוכנית. אפשר לבדוק:
System.out.println(System.getProperty("user.dir"));
דוגמה מלאה: קורא וכותב
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.ArrayList;
public class FileDemo {
public static void main(String[] args) throws IOException {
Path input = Path.of("names.txt");
Path output = Path.of("uppercased.txt");
// קריאת קובץ
List<String> names = Files.readAllLines(input);
// עיבוד
List<String> upper = new ArrayList<>();
for (String name : names) {
upper.add(name.toUpperCase());
}
// כתיבה
Files.write(output, upper);
System.out.println("הומר " + names.size() + " שמות");
}
}
דוגמה: ספירת שורות בקובץ
Path path = Path.of("data.txt");
long lineCount = Files.lines(path).count();
System.out.println("שורות: " + lineCount);
בדקו את עצמכם
נסו לענות לבד לפני שאתם פותחים את התשובה.
-
מה מייצג אובייקט
File?הצגת התשובה
תשובה א. File מתאר נתיב. כדי לקרוא תוכן משתמשים ב-Files או ב-Reader.
-
למה משתמשים ב-try-with-resources בקריאת קבצים?
הצגת התשובה
תשובה א. try(...) סוגר את המשאב בסוף הבלוק בכל מקרה.