Dziś popracujemy sobie z plikami! Temat wcale nie jest taki oczywisty – Java udostępnia nam wiele możliwości aby zapisać dane do pliku. Postaram się omówić najczęściej używane opcje oraz różnice między nimi. Zaczynamy!
01. BufferedWriter
Pierwszą sposób zapisu do pliku jaki przedstawię, jest użycie klasy BufferWriter:
public static void createAndWriteToNewFile(String fileName, String content) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) { writer.write(content); } }
Jest to bardzo podstawowa metoda która utworzy nam plik, oraz wypisze w nim to co podaliśmy w metodzie write. W tym momencie należy wspomnieć że wielokrotne uruchomienie tej metody nie spowoduje dodanie do pliku niczego nowego – za każdym razem plik będzie nadpisywany.
Warto również zaznaczyć że BufferWriter jest tworzony w bloku “try with resources”, dzięki temu nie musimy się martwić że jakieś zasoby nie zostaną zamknięte w momencie gdy kończymy pracę.
Żeby dodać do pliku kolejne informacje musimy użyć metody append.
public static void appendFileWithBufferedWriter(String fileName, String content) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true))) { writer.append(' '); writer.append(content); } }
02. PrintWriter
Kolejną metodą którą możemy użyć aby zapisać informacje do pliku jest PrintWriter
public static void createAndWriteToNewFilePrintWriter(String fileName, String content) throws IOException { try (PrintWriter writer = new PrintWriter(new FileWriter(fileName))) { writer.println(content); } }
Istnieją pewne różnice pomiędzy BufferedWriter a PrintWriter – PrintWriter posiada dodatkowe metody które mogą nam nieco ułatwić pracę z plikami, właściwie z PrintWriterem możemy pracować tak jak byśmy chcieli wypisać informacje na konsolę.
Jednak PrintWriter “połyka” błędy, zauważ że podczas pracy z PrintWriterem, metody zapisu nie deklarują wyrzucanego wyjątku:
public void println(String x) {...}
Może być to naprawdę problematyczne – w momencie gdy pójdzie coś nie tak, nie dowiemy się o tym, aby sprawdzić czy pojawił się jakiś problem musimy użyć metody checkError.
03. FileOutputStream oraz DataOutputStream
FileOutputStream jest klasą która pozwoli nam pracować z danymi w postaci binarnej
public void howToUseFOS(String fileName, String content) throws IOException { try (FileOutputStream outputStream = new FileOutputStream(fileName)) { outputStream.write(content.getBytes()); } }
DataOutputStream jest bardzo podobny do klasy opisanej wyżej – jednak pozwala na dodatkowe operacje umożliwiając nam zapis do pliku również typów prostych
try (DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(fileName))) { dataOutputStream.write(1); }
04. RandomAccessFile
RandomAccessFile jest klasą która pozwala nam edytować plik w wybranym miejscu.
public static void writeToPosition(String filename, String content, long position) throws IOException { try (RandomAccessFile writer = new RandomAccessFile(filename, "rw")) { writer.seek(position); writer.write(content.getBytes()); } }
05. Files
Od Javy 7 pojawiła się klasa która nieco ułatwia nam podstawową pracę z pikami. Zamiast zastanawiać się co wybrać – możemy użyć klasy Files! 🙂
public static void java7FilesMethod(String fileName) throws IOException { List<String> lines = Arrays.asList("The first line", "The second line"); Files.write(Paths.get(fileName), lines); }
Podsumowanie
Warto wspomnieć że nie są to wszystkie możliwe metody zapisu do pliku, istnieje np. klasa FileChannel która przeznaczona jest do pracy z dużymi plikami. Istnieje również szereg klas które ułatwiają nam pracę z plikami – np. pozawalają na założenie “locka” – powoduje to zablokowanie pliku na inne operacje do momentu w którym nie skończymy swoich operacji.
Bardzo ważną rzeczą jest zamknięcie strumienia danych po zakończonej pracy, najlepiej użyć bloku try-with-resources jak było to pokazane w powyższych przykładach.
Najczęstsze użycia:
PrintWriter – jest używany do zapisu “formatowanego” tekstu z użyciem printf();
FileOutputStream – do zapisu binarnych danych;
DataOutputStream – do zapisu typów prymitywnych (int, long, double etc.);
RandomAccessFile – do edycji pliku w konkretnym miejscu;
FileChannel – do pracy z dużymi plikami.
Wpis jest częścią kursu programowania w Javie.