Sobes.tech
Middle

Jak pracować z plikami i strumieniami wejścia/wyjścia (I/O) w Kotlin?

sobes.tech AI

Odpowiedź od AI

W standardowej bibliotece Kotlin dostępne są wygodne rozszerzenia do pracy z I/O, upraszczając interakcję z java.io.

Główne podejścia i klasy:

  • Odczyt z pliku:

    • File.readBytes(): Odczytuje zawartość pliku do tablicy bajtów.
    • File.readText(): Odczytuje zawartość pliku jako łańcuch znaków (z uwzględnieniem kodowania).
    • File.forEachLine { ... }: Przetwarza każdą linię pliku.
    • File.bufferedReader(): Tworzy BufferedReader do odczytu linia po linii.
    • File.inputStream(): Tworzy InputStream do odczytu bajtów.
  • Zapis do pliku:

    • File.writeBytes(bytes): Zapisuje tablicę bajtów do pliku.
    • File.writeText(text, append): Zapisuje łańcuch znaków do pliku. append = true dodaje na końcu.
    • File.printWriter(): Tworzy PrintWriter do formatowanego zapisu tekstu.
    • File.outputStream(): Tworzy OutputStream do zapisu bajtów.
  • Praca ze strumieniami:

    • InputStream.bufferedReader(): Opakowuje InputStream w BufferedReader.
    • OutputStream.printWriter(): Opakowuje OutputStream w PrintWriter.
    • Funkcje rozszerzające copyTo(outputStream) do kopiowania zawartości między strumieniami.
  • Zarządzanie zasobami (closures):

    • Funkcje rozszerzające use { ... } do automatycznego zamykania strumieni i czytników/pisarzy, nawet w przypadku wyjątków.
import java.io.File

fun main() {
    val file = File("my_file.txt")

    // Zapis do pliku
    file.writeText("Witaj, Kotlin I/O!")
    file.appendText("\nKontynuacja linii.")

    // Odczyt linia po linii
    file.forEachLine { line ->
        println(line)
    }

    // Odczyt całej zawartości jako tekst
    val content = file.readText()
    println("\nCała zawartość pliku:")
    println(content)

    // Użycie bufferedReader z use
    file.bufferedReader().use { reader ->
        reader.lines().forEach(::println) // Odczyt przez API strumieni Java
    }

    // Kopiowanie pliku
    val newFile = File("my_file_copy.txt")
    file.inputStream().use { input ->
        newFile.outputStream().use { output ->
            input.copyTo(output) // Wygodne kopiowanie strumieni
        }
    }
}

Tabela porównawcza niektórych metod:

Metoda Cel Typ danych Linia po linii / Całość Uwagi
readBytes() Odczyt do bajtów ByteArray Całość Odpowiednie dla danych binarnych
readText() Odczyt jako tekst String Całość Przydatne dla plików tekstowych
forEachLine { } Przetwarzanie każdej linii String Linia po linii Idealne dla dużych plików tekstowych
bufferedReader() Tworzenie buforowanego czytnika N/A Strumień Elastyczna kontrola, wymaga use
writeBytes() Zapis bajtów ByteArray Całość Odpowiednie dla danych binarnych
writeText() Zapis tekstu String Całość / dodanie Przydatne dla plików tekstowych
printWriter() Tworzenie sformatowanego pisarza N/A Strumień Przydatne do sformatowanego wyjścia, wymaga use

Użycie use { ... } jest kluczowe dla bezpiecznej pracy z I/O w Kotlin, gwarantując zwolnienie zasobów. Kotlin rozszerza istniejące klasy Java (File, InputStream, OutputStream itd.) o przydatne funkcje.