1. Aliran data
Jarang ada program yang berdiri sendiri sebagai sebuah pulau. Program biasanya entah bagaimana berinteraksi dengan "dunia luar". Ini dapat terjadi dengan membaca data dari keyboard, mengirim pesan, mengunduh halaman dari Internet, atau, sebaliknya, mengunggah file ke server jarak jauh.
Kita dapat mengacu pada semua perilaku ini dalam satu kata: pertukaran data antara program dan dunia luar. Tunggu, itu bukan hanya satu kata.
Tentu saja, pertukaran data itu sendiri dapat dibagi menjadi dua bagian: menerima data dan mengirim data. Misalnya, Anda membaca data dari keyboard menggunakan Scanner
objek — ini menerima data. Dan Anda menampilkan data di layar menggunakan System.out.println()
perintah — ini mengirim data.
Dalam pemrograman, istilah "aliran" digunakan untuk menggambarkan pertukaran data. Dari mana asal istilah itu?
Dalam kehidupan nyata, Anda dapat memiliki aliran air atau aliran kesadaran. Dalam pemrograman, kami memiliki aliran data .
Aliran adalah alat serbaguna. Mereka mengizinkan program untuk menerima data dari mana saja (aliran input) dan mengirim data ke mana saja (aliran output). Jadi, ada dua jenis:
- Aliran input adalah untuk menerima data
- Aliran output adalah untuk mengirim data
Untuk membuat aliran 'nyata', pembuat Java menulis dua kelas: InputStream
dan OutputStream
.
Kelas InputStream
memiliki read()
metode yang memungkinkan Anda membaca data darinya. Dan OutputStream
kelas memiliki write()
metode yang memungkinkan Anda menulis data ke dalamnya. Mereka memiliki metode lain juga, tetapi lebih dari itu nanti.
Aliran byte
Jenis data apa yang sedang kita bicarakan? Format apa yang dibutuhkan? Dengan kata lain, tipe data apa yang didukung kelas-kelas ini?
Ini adalah kelas generik, sehingga mendukung tipe data yang paling umum — file byte
. An OutputStream
dapat menulis byte (dan array byte), dan InputStream
objek dapat membaca byte (atau array byte). Itu saja — mereka tidak mendukung tipe data lainnya.
Akibatnya, aliran ini juga disebut aliran byte .
Salah satu fitur stream adalah bahwa datanya hanya dapat dibaca (atau ditulis) secara berurutan. Anda tidak dapat membaca data dari tengah aliran tanpa membaca semua data yang datang sebelumnya.
Beginilah cara membaca data dari keyboard melalui kelas Scanner
: Anda membaca data dari keyboard secara berurutan, baris demi baris. Kami membaca satu baris, lalu baris berikutnya, lalu baris berikutnya, dan seterusnya. Tepatnya, metode untuk membaca baris disebut nextLine()
.
Penulisan data ke an OutputStream
juga terjadi secara berurutan. Contoh bagusnya adalah keluaran konsol. Anda mengeluarkan satu baris, diikuti oleh yang lain dan yang lainnya. Ini adalah output berurutan. Anda tidak dapat menampilkan baris pertama, lalu baris kesepuluh, lalu baris kedua. Semua data ditulis ke aliran keluaran hanya secara berurutan.
Aliran karakter
Anda baru-baru ini mengetahui bahwa string adalah tipe data terpopuler kedua, dan memang demikian. Banyak informasi yang disampaikan dalam bentuk karakter dan seluruh string. Komputer unggul dalam mengirim dan menerima segala sesuatu sebagai byte, tetapi manusia tidak sesempurna itu.
Berdasarkan fakta ini, pemrogram Java menulis dua kelas lagi: Reader
dan Writer
. Kelasnya Reader
mirip dengan InputStream
kelas, tetapi read()
metodenya tidak membaca byte, tetapi karakter ( char
). Kelas Writer
sesuai dengan OutputStream
kelas. Dan seperti kelasnya Reader
, ia bekerja dengan karakter ( char
), bukan byte.
Jika kita membandingkan keempat kelas ini, kita mendapatkan gambaran berikut:
Byte (byte) | Karakter (karakter) | |
---|---|---|
Membaca data |
|
|
Menulis data |
|
|
Aplikasi praktis
Kelas InputStream
, OutputStream
, Reader
dan Writer
itu sendiri tidak digunakan secara langsung oleh siapa pun, karena mereka tidak terkait dengan objek konkret apa pun dari mana data dapat dibaca (atau di mana data dapat ditulis). Tetapi keempat kelas ini memiliki banyak kelas turunan yang dapat melakukan banyak hal.
2. InputStream
kelas
Kelas ini InputStream
menarik karena merupakan kelas induk dari ratusan kelas keturunan. Itu tidak memiliki datanya sendiri, tetapi ia memiliki metode yang diwarisi oleh semua kelas turunannya.
Secara umum, objek aliran jarang menyimpan data secara internal. Aliran adalah alat untuk membaca/menulis data, tetapi bukan penyimpanan. Yang mengatakan, ada pengecualian.
Metode kelas InputStream
dan semua kelas turunannya:
Metode | Keterangan |
---|---|
|
Membaca satu byte dari aliran |
|
Membaca array byte dari aliran |
|
Membaca semua byte dari aliran |
|
Melewati n byte dalam aliran (membaca dan membuangnya) |
|
Memeriksa berapa banyak byte yang tersisa di aliran |
|
Menutup aliran |
Mari kita bahas secara singkat metode-metode ini:
read()
metode
Metode read()
membaca satu byte dari aliran dan mengembalikannya. Anda mungkin bingung dengan int
jenis pengembalian. Tipe ini dipilih karena int
merupakan tipe integer standar. Tiga byte pertama dari int
akan menjadi nol.
read(byte[] buffer)
metode
Ini adalah varian kedua dari read()
metode ini. Ini memungkinkan Anda membaca array byte dari InputStream
semua sekaligus. Larik yang akan menyimpan byte harus diteruskan sebagai argumen. Metode ini mengembalikan angka — jumlah byte yang sebenarnya dibaca.
Katakanlah Anda memiliki buffer 10 kilobyte dan Anda sedang membaca data dari file menggunakan kelas FileInputStream
. Jika file hanya berisi 2 kilobyte, semua data akan dimuat ke dalam buffer array, dan metode akan mengembalikan angka 2048 (2 kilobyte).
readAllBytes()
metode
Metode yang sangat bagus. Itu hanya membaca semua data dari InputStream
sampai habis dan mengembalikannya sebagai array byte tunggal. Ini sangat berguna untuk membaca file kecil. File besar mungkin tidak muat secara fisik di memori, dan metode ini akan mengeluarkan pengecualian.
skip(long n)
metode
Metode ini memungkinkan Anda untuk melewati n byte pertama dari objek InputStream
. Karena data dibaca secara berurutan, metode ini hanya membaca n byte pertama dari aliran dan membuangnya.
Mengembalikan jumlah byte yang benar-benar dilewati (jika streaming berakhir sebelum n
byte dilewati).
int available()
metode
Metode mengembalikan jumlah byte yang masih tersisa di aliran
void close()
metode
Metode close()
menutup aliran data dan melepaskan sumber daya eksternal yang terkait dengannya. Setelah aliran ditutup, tidak ada lagi data yang dapat dibaca darinya.
Mari kita tulis contoh program yang menyalin file yang sangat besar. Kami tidak dapat menggunakan readAllBytes()
metode untuk membaca seluruh file ke dalam memori. Contoh:
Kode | Catatan |
---|---|
|
InputStream untuk membaca dari file OutputStream untuk menulis ke file Buffer di mana kita akan membaca data Selama ada data di aliran Baca data ke dalam buffer Tulis data dari buffer ke aliran kedua |
Dalam contoh ini, kami menggunakan dua kelas: FileInputStream
adalah turunan InputStream
untuk membaca data dari file, dan FileOutputStream
turunan OutputStream
untuk menulis data ke file. Kami akan berbicara tentang kelas kedua nanti.
Poin menarik lainnya di sini adalah variabelnya real
. Saat blok data terakhir dibaca dari sebuah file, file tersebut dapat dengan mudah memiliki kurang dari 64KB data. Oleh karena itu, kita perlu menampilkan bukan seluruh buffer, tetapi hanya sebagian — real
byte pertama. Inilah yang terjadi dalam write()
metode ini.
3. Reader
kelas
Kelas Reader
adalah analog lengkap dari InputStream
kelas. Satu-satunya perbedaan adalah ia bekerja dengan karakter ( char
), bukan dengan byte. Sama seperti InputStream
class, Reader
class tidak digunakan di mana pun dengan sendirinya: ini adalah class induk dari ratusan class turunan dan mendefinisikan metode umum untuk semuanya.
Metode kelas Reader
(dan semua kelas turunannya):
Metode | Keterangan |
---|---|
|
Membaca satu char dari aliran |
|
Membaca char array dari aliran |
|
Melewatkan n chars arus (membaca dan membuangnya) |
|
Memeriksa apakah masih ada sesuatu yang tersisa di aliran |
|
Menutup aliran |
Metodenya sangat mirip dengan kelasnya InputStream
, meskipun ada sedikit perbedaan.
int read()
metode
Metode ini membaca satu char
dari aliran dan mengembalikannya. Jenis char
melebar ke int
, tetapi dua byte pertama hasilnya selalu nol.
int read(char[] buffer)
metode
Ini adalah varian kedua dari read()
metode ini. Ini memungkinkan Anda membaca array char dari Reader
sekaligus. Larik yang akan menyimpan karakter harus diteruskan sebagai argumen. Metode mengembalikan angka — jumlah karakter yang benar-benar dibaca.
skip(long n)
metode
Metode ini memungkinkan Anda untuk melewati n karakter pertama dari objek Reader
. Ini bekerja persis sama dengan metode analog kelas InputStream
. Mengembalikan jumlah karakter yang benar-benar dilewati.
boolean ready()
metode
Mengembalikan true
jika ada byte yang belum dibaca di aliran.
void close()
metode
Metode close()
menutup aliran data dan melepaskan sumber daya eksternal yang terkait dengannya. Setelah aliran ditutup, tidak ada lagi data yang dapat dibaca darinya.
Sebagai perbandingan, mari kita tulis program yang menyalin file teks:
Kode | Catatan |
---|---|
|
Reader untuk membaca dari sebuah file Writer untuk menulis ke sebuah file Buffer dimana kita akan membaca data Selama ada data di dalam stream Membaca data ke dalam buffer Menulis data dari buffer ke stream kedua |
GO TO FULL VERSION