Fungsi available() Pada Java
Dalam pemrograman Java, khususnya saat bekerja dengan InputStream, ada satu method yang sering bikin penasaran,
yaitu available()
. Method ini kadang dianggap sepele, tapi sebenarnya cukup berguna dalam situasi
tertentu. Kalau kita perhatikan, available()
dapat membantu mengetahui perkiraan jumlah byte
yang siap dibaca tanpa harus menunggu. Walaupun tidak selalu akurat 100%, tetapi informasi ini sangat bermanfaat
untuk mengoptimasi pembacaan data atau bahkan sekadar memastikan apakah masih ada data yang bisa dibaca
sebelum kita benar-benar menutup stream.
Artikel ini akan membahas secara menyeluruh tentang apa itu available()
, bagaimana cara
kerjanya, dan kapan kita bisa memanfaatkannya. Kita juga akan melihat beberapa contoh penggunaan di berbagai
kasus—mulai dari penggunaan sederhana dengan FileInputStream
hingga skenario yang lebih kompleks
seperti streaming data dari socket jaringan.
Apa Itu available()
?
Secara umum, available()
adalah sebuah method yang terdapat di InputStream
(dan turunan-turunannya) di Java. Method ini mengembalikan nilai integer yang merepresentasikan jumlah byte
yang “mungkin†dapat dibaca tanpa melakukan blocking. Artinya, kalau kita memanggil
InputStream.available()
, kita akan mendapatkan informasi tentang seberapa banyak data yang
ready to read pada saat itu.
Penting untuk dicatat bahwa nilai yang dikembalikan oleh available()
bukanlah jaminan
bahwa selalu tepat sama dengan jumlah byte yang betul-betul tersedia, karena kondisi streaming data bisa berubah
kapan saja. Namun, biasanya jika kita hanya membaca data dari sumber statis seperti file, nilai
available()
cenderung cukup akurat (selama file itu tidak dimodifikasi oleh proses lain).
Dalam konteks jaringan, karena data bisa masuk dan keluar secara dinamis, hasilnya bisa lebih fluktuatif.
Kenapa available()
Penting?
- Efisiensi: Dengan mengetahui berapa banyak byte yang sudah siap dibaca, kita bisa menyesuaikan buffer yang dipakai untuk membaca data. Hal ini dapat meningkatkan efisiensi operasi I/O.
- Pencegahan Blocking Berlama-lama: Saat kita melakukan pembacaan data yang berpotensi
block (misalnya menunggu data dari socket), kita bisa melakukan pengecekan awal dengan
available()
untuk melihat apakah ada data yang siap. Meskipun tidak menjamin 100%, tapi bisa membantu menekan kemungkinan thread tertahan terlalu lama. - Validasi Sederhana: Terkadang kita ingin sekadar tahu apakah masih ada data yang tersisa
sebelum melakukan operasi lainnya.
available()
bisa membantu kita menentukan apakah kita masih perlu melanjutkan pembacaan atau sudah waktunya menutup stream.
Cara Kerja available()
Sebelum kita masuk ke contoh, mari kita sedikit membahas bagaimana available()
bekerja di
InputStream
. Berikut adalah deskripsi singkat:
InputStream
adalah class abstrak yang mendefinisikan kontrak dasar untuk membaca byte dari sebuah sumber, bisa file, socket, array, dan sebagainya.- Karena
InputStream
bersifat abstrak,available()
di dalamnya biasanya mengembalikan 0 atauthrow IOException
. - Subclass seperti
FileInputStream
atauByteArrayInputStream
mengoverride methodavailable()
untuk memberikan nilai yang lebih relevan dengan konteks sumber data mereka.
Contohnya, pada ByteArrayInputStream
, method available()
akan mengembalikan sisa byte
yang masih bisa dibaca dari buffer internal. Sementara itu, pada FileInputStream
,
available()
berusaha mengembalikan perkiraan jumlah byte yang masih tersedia untuk dibaca dari
file sistem, meskipun itu bukan jaminan final (karena file bisa berubah-ubah jika ada proses lain yang
memodifikasinya, walaupun hal ini tergolong kasus khusus).
Contoh Penggunaan Sederhana dengan FileInputStream
Mari kita mulai dengan contoh termudah. Kita akan menggunakan FileInputStream
untuk membaca sebuah
file teks sederhana. Anggaplah kita punya file bernama contoh.txt yang isinya tidak terlalu besar.
import java.io.FileInputStream;
import java.io.IOException;
public class AvailableExample {
public static void main(String[] args) {
String filePath = "contoh.txt";
try (FileInputStream fis = new FileInputStream(filePath)) {
// Cek jumlah byte yang tersedia
int availableBytes = fis.available();
System.out.println("Bytes yang tersedia sebelum pembacaan: " + availableBytes);
// Baca data sampai selesai
int data;
while ((data = fis.read()) != -1) {
// Lakukan sesuatu dengan data
}
// Cek kembali
System.out.println("Bytes yang tersedia setelah pembacaan: " + fis.available());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pada contoh di atas, kita membuka file contoh.txt menggunakan FileInputStream
.
Lalu kita panggil fis.available()
untuk melihat berapa byte yang siap dibaca. Biasanya,
available()
akan mengembalikan nilai sama dengan ukuran file (jika file-nya belum dibaca sama
sekali). Setelah kita membaca semua data dari file, nilai available()
biasanya menjadi 0,
menandakan sudah tidak ada data lagi yang tersisa di stream.
Contoh Penggunaan dengan ByteArrayInputStream
ByteArrayInputStream
sering dipakai saat kita ingin melakukan simulasi pembacaan data
dari sumber memori (array of bytes). Bagi yang sering melakukan unit testing,
ByteArrayInputStream
sangat berguna. Bagaimana dengan available()
di class ini?
Yuk kita lihat contohnya:
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class ByteArrayAvailableExample {
public static void main(String[] args) {
byte[] data = "Halo, ini data simulasi!".getBytes();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data)) {
System.out.println("Bytes tersedia di awal: " + bais.available());
// Baca 5 byte pertama
for (int i = 0; i < 5; i++) {
bais.read();
}
System.out.println("Bytes tersedia setelah baca 5 byte: " + bais.available());
// Baca sisa byte
while (bais.read() != -1) {
// Proses data
}
System.out.println("Bytes tersedia setelah semua data dibaca: " + bais.available());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Di sini, data
adalah array byte yang berisi string "Halo, ini data simulasi!".
Ketika baru pertama kali kita membuat ByteArrayInputStream
, isi bais.available()
akan sama dengan panjang string tersebut (dalam satuan byte). Saat kita membaca sebagian data, nilai
available()
akan berkurang. Ketika semua byte sudah habis dibaca, nilainya akan jadi 0.
Penggunaan pada Socket (Stream Jaringan)
Situasi menjadi lebih menarik saat kita bekerja dengan socket. Data yang mengalir melalui jaringan
bisa datang kapan saja, dan available()
bisa memberikan kita petunjuk apakah ada data yang siap
dibaca di buffer. Namun, kita harus hati-hati karena available()
tidak menjamin bahwa
jumlah byte yang dilaporkan sudah mencakup semua data yang akan datang, terutama jika data dikirim secara
bertahap oleh server atau klien.
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketAvailableExample {
public static void main(String[] args) {
// Contoh sangat sederhana: kita bikin server socket di port 1234
try (ServerSocket serverSocket = new ServerSocket(1234)) {
System.out.println("Menunggu koneksi di port 1234...");
// Terima koneksi
Socket clientSocket = serverSocket.accept();
System.out.println("Klien terhubung: " + clientSocket.getInetAddress());
// Dapatkan input stream dari socket
InputStream input = clientSocket.getInputStream();
// Cek ketersediaan data
int availableBytes = input.available();
System.out.println("Bytes tersedia saat ini: " + availableBytes);
// Baca data jika ada
if (availableBytes > 0) {
byte[] buffer = new byte[availableBytes];
int read = input.read(buffer);
System.out.println("Data diterima: " + new String(buffer, 0, read));
}
// Tutup koneksi
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pada contoh di atas, kita membuat server socket sederhana di port 1234. Setelah menerima koneksi dari klien,
kita memanggil input.available()
untuk mengetahui berapa banyak byte yang “kemungkinan†siap dibaca.
Kalau nilai tersebut lebih besar dari nol, kita langsung baca semuanya. Kalau tidak, kita bisa menunggu sejenak
atau melakukan hal lain.
Kelemahannya, data bisa saja datang setelah kita memanggil available()
. Jadi, kalau kita
memperlakukan nilai available()
sebagai patokan final, kita mungkin berisiko tidak membaca data
yang datang setelahnya. Oleh karena itu, untuk data streaming, kita tetap biasanya menggunakan mekanisme
blocking read dengan read()
atau read(byte[] buffer)
secara berulang sambil
memantau apakah stream masih menyuplai data.
Kapan available()
Sebaiknya Dipakai?
Meskipun available()
kelihatannya gampang digunakan, kita perlu tahu waktu yang tepat untuk
menggunakannya. Beberapa skenario yang masuk akal untuk memanfaatkan available()
antara lain:
- Mengoptimasi Pembacaan File: Saat bekerja dengan file yang ukurannya tidak terlalu
besar atau saat kita ingin tahu berapa sisa byte yang belum dibaca,
available()
bisa membantu penyesuaian buffer untuk membaca file secara efisien. - Validasi Cepat Sebelum Read Non-Blocking: Di beberapa situasi, kita bisa
melakukan pengecekan cepat di mana jika
available()
mengembalikan 0, kita bisa memutuskan untuk tidak memanggilread()
. Hal ini dapat menghindari blocking yang tidak perlu, meskipun tidak menutup kemungkinan data akan masuk setelahnya. - Debugging: Terkadang
available()
dipakai untuk keperluan debugging, misalnya sekadar ingin tahu apakah stream-nya masih mengandung data atau tidak pada titik tertentu dalam kode.
Kapan Sebaiknya Menghindari available()
?
Di sisi lain, ada situasi di mana available()
tidak terlalu bermanfaat atau bahkan bisa
menimbulkan kebingungan:
- Pembacaan Data yang Sudah Terstruktur: Jika kita sudah tahu bahwa data yang dikirim
akan mengikuti protokol tertentu (misalnya selalu ada header yang mengatakan panjang data), maka
available()
jadi kurang relevan. Kita bisa membaca data sesuai protokol tanpa harus bergantung padaavailable()
. - Streaming Real-time: Saat membaca data real-time dari jaringan yang terus berubah,
available()
mungkin hanya berguna sesaat. Biasanya kita akan tetap melakukan pembacaan secara blocking atau non-blocking menggunakan mekanisme NIO (New I/O) dengan selektor dan lain-lain. - Keperluan Large File I/O Khusus: Kalau kita sedang berurusan dengan file
berukuran sangat besar, seringkali kita tidak peduli berapa banyak byte yang tersedia. Kita akan melakukan
pembacaan per blok atau chunk menggunakan buffer dengan ukuran tertentu.
available()
tidak banyak membantu di sini, karena kita tetap harus membaca seluruh data hingga selesai.
Perbedaan dengan mark()
dan reset()
Meskipun sedikit melenceng, tapi sering kali available()
, mark()
, dan
reset()
disebut secara bersamaan dalam pembahasan tentang InputStream
di Java.
Hanya sekadar untuk meluruskan:
mark(int readlimit)
digunakan untuk menandai posisi saat ini pada stream, sehingga nanti kita bisareset()
ke posisi tersebut.reset()
mengembalikan pointer pembacaan ke posisi di manamark()
pertama kali dipanggil.available()
tidak ada kaitannya denganmark()
danreset()
secara langsung. Ia hanya mengukur ketersediaan data di buffer, bukan posisi pointer pembacaan.
Contoh Penggunaan Lain: SequenceInputStream
Selain FileInputStream
dan ByteArrayInputStream
, Java juga punya
SequenceInputStream
. Class ini menggabungkan beberapa InputStream
menjadi satu
stream berkesinambungan. available()
di SequenceInputStream
akan mengembalikan
jumlah byte yang tersedia di stream aktif saat itu, bukan total seluruh InputStream
yang digabung. Berikut contohnya:
import java.io.*;
public class SequenceAvailableExample {
public static void main(String[] args) {
byte[] data1 = "Data Pertama".getBytes();
byte[] data2 = "Data Kedua".getBytes();
try (ByteArrayInputStream bais1 = new ByteArrayInputStream(data1);
ByteArrayInputStream bais2 = new ByteArrayInputStream(data2);
SequenceInputStream sis = new SequenceInputStream(bais1, bais2)) {
System.out.println("Bytes tersedia diawal: " + sis.available());
// Baca data pertama
while (bais1.available() > 0) {
sis.read();
}
// Sekarang stream internal berganti ke data2
System.out.println("Bytes tersedia setelah data1 habis: " + sis.available());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pada contoh ini, SequenceInputStream
akan membaca semua byte dari bais1
terlebih dahulu, baru kemudian beralih ke bais2
. Nilai available()
yang kita dapat
bisa berubah begitu bais1
selesai dibaca dan stream pindah ke bais2
.
Tips dan Trik Seputar available()
Setelah melihat beberapa contoh, berikut adalah beberapa tips dan trik yang mungkin berguna:
- Gunakan
available()
dengan Pemahaman yang Tepat: Jangan pernah berasumsi bahwa jumlah byte yang dikembalikan olehavailable()
adalah keseluruhan data yang akan datang. Ini hanya perkiraan jumlah byte yang bisa dibaca secara instan. - Jangan Lupa Tangani IOException: Memanggil
available()
bisa memunculkanIOException
. Meskipun jarang terjadi untuk stream tertentu, tetaplah siap dengantry-catch
. - Tetap Gunakan Mekanisme Baca Standar: Kalau tujuan utama kita hanya membaca seluruh
isi file atau stream, mekanisme baca dengan
read()
atauread(byte[] buffer)
berulang sudah lebih dari cukup. - Buffering Manual vs. Otomatis: Untuk performa yang lebih baik, kita bisa
menggabungkan
available()
dengan alokasi buffer yang dinamis. Namun, Java sudah punyaBufferedInputStream
yang cukup cerdas mengelola buffer secara internal.
Studi Kasus: Membaca File Biner dengan Ukuran Sedang
Misalnya kita ingin membaca file biner dengan ukuran sekitar 2MB dan menampilkannya dalam bentuk heksadesimal
di layar. Kita bisa memanfaatkan available()
untuk memberi petunjuk seberapa banyak data yang
tersisa, meskipun sebenarnya tidak wajib. Contoh kode berikut hanya untuk ilustrasi:
import java.io.FileInputStream;
import java.io.IOException;
public class BinaryFileHexDump {
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Usage: java BinaryFileHexDump ");
return;
}
String filePath = args[0];
try (FileInputStream fis = new FileInputStream(filePath)) {
int availableBytes;
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
// Cetak heksadesimal
for (int i = 0; i < bytesRead; i++) {
System.out.printf("%02X ", buffer[i]);
}
System.out.println();
availableBytes = fis.available();
System.out.println("Bytes tersisa menurut available(): " + availableBytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Pada kode di atas, setelah setiap kali kita membaca chunk data sebesar 1024 byte (atau kurang di putaran
terakhir), kita mencetak data tersebut dalam format heksadesimal, lalu menanyakan lagi berapa jumlah byte
yang masih tersedia. Meskipun ini tidak esensial untuk proses pembacaan, ini sekadar menunjukkan bagaimana
available()
bisa memberikan snapshot singkat tentang status sisa data di stream.
Method available()
dalam InputStream
di Java adalah fitur yang relatif sederhana,
tetapi cukup berguna dalam skenario tertentu. Kita bisa memakainya untuk:
- Mengoptimasi pembacaan file berukuran kecil hingga sedang.
- Melakukan pengecekan cepat untuk data yang siap dibaca pada socket jaringan.
- Menyesuaikan ukuran buffer secara dinamis saat melakukan streaming data dari berbagai sumber.
Namun, perlu diingat bahwa available()
bukanlah metode yang bisa dijadikan patokan mutlak untuk
menilai total jumlah data yang akan datang, terutama dalam konteks jaringan dan file yang bisa
dimodifikasi oleh proses lain. Menggunakannya secara bijak dan memahami keterbatasannya adalah
kunci untuk menghindari kesalahpahaman.
Jadi, kalau kamu sedang ngulik stream di Java dan bertanya-tanya berapa banyak data yang masih bisa dibaca
saat ini, available()
bisa memberikan jawabannya—walaupun tidak harus lengkap, setidaknya
cukup untuk memberikan heads up sebelum kamu melanjutkan operasi I/O selanjutnya.
Semoga artikel ini membantu kamu memahami available()
lebih dalam dan kapan kamu bisa
memanfaatkan fitur ini. Selamat mencoba dan semoga sukses dalam pemrograman Java kamu!
Baca Juga :