Stream, Reader, dan Writer
OutputStream
. Objek yangmembaca data dari aliran byte diturunkan dari kelas abstrak InputStream
. Jika kita menulis angka ke suatu OutputStream
, kita tidak akan bisa membaca data tersebut karena ditulis dalam bahasa mesin. Akan tetapi data tersebut bisa dibaca kembali olehInputStream
. Proses baca tulis data akan menjadi sangat efisien, karena tidak ada penerjemahan yang harus dilakukan : bit yang digunakan untuk menyimpan data di dalam memori komputer hanya dikopi dari dan ke aliran tersebut.Reader
dan Writer
. Semua kelas aliran karakter merupakan kelas turunan dari salah satu dari kelas abstrak ini. Jika suatu angka akan ditulis dalam aliranWriter
, komputer harus bisa menerjemahkannya ke dalam rangkaian karakter yang bisa dibaca maunsia.Reader
menjadi variabel numerik juga harus diterjemahkan, dari deretan karakter menjadi rangkaian bit yang dimengerti komputer. (Meskipun untuk data yang terdiri dari karakter, seperti dari editor teks, masih akan ada beberapa terjemahan yang dilakukan. Karakter disimpan dalam komputer dalam nilai Unicode 16-bit. Bagi orang yang menggunakan alfabet biasa, data karakter biasanya disimpan dalam file dalam kode ASCII, yang hanya menggunakan 8-bit. Kelas Reader
dan Writer
akan menangani perubahan dari 16-bit ke 8-bit dan sebaliknya, dan juga menangani alfabet lain yang digunakan negara lain.)System.in
danSystem.out
sebenarnya adalah aliran byte dan bukan aliran karakter, karenanya bisa menangani input selain alfabet, misalnya tombol enter, tanda panah, escape, dsb.java.io
beserta beberapa kelas bantu lainnya. Kita harus mengimpor kelas-kelas tersebut dari paket ini jika kita ingin menggunakannya dalam program kita. Artinya dengan menggunakan "import java.io.*
" di awal kode sumber kita.File
FileReader
yang merupakan kelas turunan Reader
. Data bisa ditulis dalam bentuk yang bisa dibaca manusia dengan menggunakan FileWriter
yang merupakan kelas turunan dari Writer
.FileInputStream
danFileOutputStream
. Semua kelas ini didefinisikan dalam paket java.io
.FileReader
memiliki konstruktor yang mengambil nama file sebagai parameternya, kemudian membuat aliran input yang bisa digunakan untuk membaca file tersebut. Konstruktor ini akan melemparkan pengecualian bertipe FileNotFoundException
jika file tersebut tidak ditemukan.try
atau menambahkan pernyataan throw
di kepala subrutin yang menjalankan konstruktor tersebut. Milsanya, anggap kita memiliki file bernama "data.txt
", dan kita ingin membuat program untuk membaca data pada file tersebut. Kita bisa menggunakan pernyataan berikut untuk membaca aliran input dari file tersebut :// (Mendeklarasikan variabel sebelum pernyataan try
// jika tidak, maka variabel tersebut hanya bisa
// dilihat di dalam blok try, dan kita tidak bisa
// menggunakannya lagi di bagian program lain
FileReader data;
try {
// buat aliran input
data = new FileReader("data.txt");
}
catch (FileNotFoundException e) {
... // lakukan sesuatu untuk menangani kesalahan
}
FileNotFoundException
merupakan kelas turunan dari IOException
, sehingga kita bisa menangkap IOException
pada pernyataan try...catch
di atas. Secara umum, hampir semua kesalahan yang terjadi pada saat operasi input/output dapat ditangkap dengan pernyataan catch
yang menangani IOException
.FileReader
, kita bisa mulai membacanya. Tapi karena FileReader
hanya memiliki metode input primitif dari standar kelas Reader
, kita mungkin akan perlu membungkusnya dalam objek lain, misalnya BufferedReader
atau kelas pembungkus lain. Untuk membuat BufferedReader
untuk membaca file bernama "data.dat", kita bisa gunakan :TextReader data;
try {
data = new BufferedReader(new FileReader("data.dat"));
}
catch (FileNotFoundException e) {
... // tangani pengecualian
}
BufferedReader
memiliki metode bantu untuk mengambil data per baris dengan perintah readline()
. Sehingga apabila satu data ditulis dalam urutan per baris, kita bisa gunakan perintah Double.parseDouble(string) atau Integer.parseInt(string) untuk mengubahnya menjadi double atau int.FileWriter
. Dan kemudian kita mungkin ingin membungkus aliran output ini dalam objek PrintWriter
. Misalnya, kita ingin menyimpan data ke file yang bernama "hasil.dat", kita bisa menggunakan :PrintWriter result;
try {
keluaran = new PrintWriter(new FileWriter("hasil.dat"));
}
catch (IOException e) {
... // tangani pengecualian
}
IOException
bisa terjadi jika, misalnya, file tersebut sedang dibaca oleh program lain, sehingga sistem operasi menolak program kita untuk menulisnya pada saat yang sama.close()
pada aliran tersebut. Setelah file telah ditutup, maka kita tidak mungkin lagi membaca atau menulis data dari atau ke file tersebut. Kita harus membukanya kembali. (Perlu dicatat bahwa penutupan file juga bisa melemparkan pengecualian IOException
yang wajib ditangani, akan tetapi PrintWriter
menangani pengecualian tersebut secara otomatis sehingga kita tidak perlu menanganinya lagi).package balikfile;
import java.io.*;
public class BalikFile {
/**
* @param args
*/
public static void main(String[] args) {
BufferedReader data; // Aliran input karakter untuk membaca data
PrintWriter hasil; // Aliran output karakter untuk menulis data
// Array untuk menampung semua angka dari dalam file
double[] angka = new double[1000];
int banyakAngka; // Banyaknya angka yg disimpan dlm array
try { // Buat aliran input
data = new BufferedReader(new FileReader("data.dat"));
}
catch (FileNotFoundException e) {
System.out.println("Tidak bisa menemukan data.dat!");
return; // akhiri program
}
try { // Membuat aliran output
hasil = new PrintWriter(new FileWriter("hasil.dat"));
}
catch (IOException e) {
System.out.println("Tidak bisa membuka hasil.dat!");
System.out.println(e.toString());
try {
data.close(); // Tutup file input
}
catch (IOException f) {
System.out.println("Tidak bisa menutup data.dat");
}
return; // End the program.
}
String baris = null; // variabel untuk menyimpan satu baris teks
try {
// Baca data dari file input
banyakAngka = 0;
while ((baris = data.readLine()) != null) { // baca hingga habis
angka[banyakAngka] = Double.parseDouble(baris);
banyakAngka++;
}
// Tulis hasilnya dalam urutan terbalik
for (int i = banyakAngka-1; i >= 0; i--)
hasil.println(angka[i]);
System.out.println("Selesai!");
}
catch (IOException e) {
// Ada masalah dengan pembacaan/penulisan file
System.out.println("Kesalahan baca/tulis");
}
catch (NumberFormatException e) {
// Ada masalah dengan format angka dalam file
System.out.println("Kesalahan format: " + e.getMessage());
}
catch (IndexOutOfBoundsException e) {
// Tidak boleh meletakkan 1000 angka dalam file
System.out.println("Terlalu banyak angka.");
System.out.println("Penulisan dihentikan.");
}
finally {
// Akhiri dengan menutup semua file apapun yang terjadi
try {
data.close(); // Tutup file input
}
catch (IOException e) {
System.out.println("Tidak bisa menutup data.dat");
}
hasil.close(); // Tutup file output
}
}
}
Nama File, Direktori, dan Kelas File
- data.dat -- pada komputer apapun, yaitu file data.dat pada direktori aktif.
- /home/lyracc/java/contoh/data.dat -- Nama path absolut pada sistem operasi LINUX atau UNIX. Mengacu pada file bernama data.dat di direktori yang ditunjuk.
- C:\lyracc\java\contoh\data.dat -- Nama path absolut pada DOS atau Windows
- Hard Drive:java:contoh:data.dat -- Misalnya "Hard Drive" adalah nama dari drivenya, maka ini adalah nama path absolut pada Macintosh OS 9
- contoh/data.dat -- nama path relatif pada LINUX atau UNIX. "contoh" adalah nama direktori yang terdapat pada direktori aktif, dan data.dat adalah file dalam direktori tersebut. Pada Windows, nama path relatifnya menjadi contoh\data.dat dan pada Macintosh menjadi contoh:data.dat.
java.io.File
. Objek bertipe kelas ini melambangkan suatu file. Lebih tepatnya, objek bertipe File
melambangkan nama file, bukan file itu sendiri. Nama yang ditunjuk belum tentu ada. Direktori juga dianggap Java sebagai File
, sehingga File
juga melambangkan nama direktori sekaligus nama file.File
memiliki konstruktor new File(String)
yang akan membuat objek File
dari namanya. Nama tersebut bisa nama sederhana, nama path relatif, atau nama path absolut. Misalnya new File("data.dat")
membuat objek File
dari file bernama data.dat di direktori aktif.new File(File,String)
, di mana parameter pertama adalah direktori di mana file tersebut berada, dan parameter kedua adalah nama filenya.File
memiliki beberapa metode instansi. Misalnya file
adalah variabel bertipe File
, berikut ini adalah beberapa metodenya :file.exists()
-- mengembalikan nilai boolean, yang jika true maka file tersebut ada. Kita bisa menggunakan perintah ini misalnya untuk mencegah menulis file yang sama ketika kita membuka objekFileWriter
baru.file.isDirectory()
-- mengembalikan nilai boolean yang mengembalikan true jika objekFile
adalah suatu direktori, dan false jikaFile
adalah file biasa, atau tidak ada file dengan nama tersebut.file.delete()
-- menghapus file jika adafile.list()
-- jika objekFile
adalah suatu direktori, maka fungsi ini mengembalikan array bertipe String[] yang berisi nama-nama file pada direktori tersebut. Jika tidak, maka kembaliannya adalah null.
package daftardirektori;
import java.io.*;
public class DaftarDirektori {
/* Program ini mengembalikan isi suatu direktori
* User memasukkan direktori yang ingin dilihat
* Jika direktori tidak ada, maka pesan kesalahan
* akan ditulis dan program akan berhenti
*/
public static void main(String[] args) {
String namaDirektori = null; // Nama direktori dari user
File direktori; // objek File yang mengacu pada direktori
String[] isiFile; // Array berisi file pada direktori
// buat objek baru untuk mengambil input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Masukkan nama direktori : ");
try {
namaDirektori = br.readLine();
} catch(IOException ioe) {
System.out.println("Kesalahan IO terjadi");
System.exit(1);
}
direktori = new File(namaDirektori);
if (direktori.isDirectory() == false) {
if (direktori.exists() == false)
System.out.println("Tidak ada direktori ini!");
else
System.out.println("Ini bukan direktori.");
}
else {
isiFile = direktori.list();
System.out.println("Files dalam direktori \"" + direktori + "\":");
for (int i = 0; i < isiFile.length; i++)
System.out.println(" " + isiFile[i]);
}
}
}
File
sebagai parameternya. Misalnya, jika file
adalah variabel bertipe File
, dan kita ingin mengambil karakter dari file tersebut, maka kita bisa membuat FileReader
untuk melakukannya dengan menggunakan new FileReader(file)
.Mengkopi File
InputStream
dan OutputStream
untuk melakukan operasi baca tulis yang bisa menangani data biner, bukan Reader
dan Writer
yang hanya bisa menangani data yang bisa dibaca manusia.InputStream
ke OutputStream
, akan tetapi kita membutuhkan tempat sementara di mana data tersebut akan ditempatkan sebelum data tersebut ditulis kembali padaOutputStream
. Tempat sementara tersebut disebut buffer yang merupakan array berukuran tertentu, misalnya 4096 byte (atau 4 kilo byte).sumber
adalah variabel bertipe InputStream
, maka byteTerbaca = sumber.read(buffer)
akan mengisi penuh buffer. Metode ini mengembalikan int yang merupakan berapa byte yang efektif diambil oleh sumber
, kemudian diletakkan dalam variabelbyteTerbaca
. Jika hasilnya -1, berarti tidak ada lagi data yang bisa diambil dari dalam sumber.kopi
adalah keluaran yang bertipe OutputStream
maka kopi.write(buffer, 0, byteTerbaca)
menulis deretan byte dari buffer dari posisi 0 hingga byteTerbaca
ke aliran keluaran kopi
.byte[] buffer = new byte[4096];
int byteTerbaca;
while((byteTerbaca = sumber.read(buffer)) != -1)
kopi.write(buffer, 0, byteTerbaca);
copy awal.datakhir.dat
" untuk mengkopi file awal.dat
ke file bernama akhir.dat
.main()
. Ingat bagaimana "biasanya" subrutin main()
dideklarasikan sebagai public static voidmain(String[] args)
.java KopiFile awal.dat akhir.dat
" jika KopiFile adalah nama kelas yang akan kita buat untuk mengkopi file. args[0]
akan berisi awal.dat
sedangkan args[1]
akan berisi akhir.dat
.awal.dat
. Jika ya, maka operasi akan diteruskan, jika tidak maka program akan dihentikan.import java.io.*;
public class KopiFile {
/**
* @param args
*/
public static void main(String[] args) {
// Mengecek apakah argumen program cukup untuk meneruskan program
// Dibutuhkan dua argumen, yaitu sumberFile dan tujuanFile
if (args.length < 2) {
System.out.println("Cara menjalankan program : " +
"java KopiFile sumberFile tujuanFile");
return;
}
String sumberNamaFile = args[0];
String tujuanNamaFile = args[1];
File sumberFile = new File(sumberNamaFile);
File kopiFile = new File(tujuanNamaFile);
// Jika kopi file sudah ada, kita akan tanyakan apakah file tujuan
// akan ditimpa
if (kopiFile.exists()) {
// buat objek baru untuk mengambil input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String timpaFile = null;
System.out.print("Apakah Anda ingin menimpa " + tujuanNamaFile + " ? (y/t) ");
try {
timpaFile = br.readLine();
} catch(IOException ioe) {
System.out.println("Kesalahan IO terjadi");
System.exit(1);
}
// jika jawabannya tidak, hentikan program
if (timpaFile.equalsIgnoreCase("t"))
return;
}
// Di sini kita siap untuk mengkopi file
// Buat aliran input dan output
FileInputStream sumber = null;
try {
sumber = new FileInputStream(sumberFile);
} catch (FileNotFoundException e) {
System.out.println("File sumber tidak ada, berupa direktori " +
"atau tidak bisa dibuka, program dihentikan!");
return;
}
FileOutputStream kopi = null;
try {
kopi = new FileOutputStream(tujuanNamaFile);
} catch (FileNotFoundException e) {
System.out.println("File tujuan tidak valid atau tidak bisa ditulis, " +
"program dihentikan!");
return;
}
byte[] buffer = new byte[4096];
int byteTerbaca;
try {
while((byteTerbaca = sumber.read(buffer)) != -1)
kopi.write(buffer, 0, byteTerbaca);
} catch (IOException e) {
System.out.println("Ada masalah di tengah pengkopian program");
return;
}
System.out.println("Kopi file selesai dijalankan!");
}
}
c:\belajarjava.lyracc.com\KopiFile
. Di dalamnya seharusnya Anda akan menemui 2 direktori, yaitu src
dan bin
. src
adalah tempat di mana kode sumber berada, sedangkan bin
adalah tempat dimana hasil kompilasi berada. Eclipse akan melakukan kompilasi secara otomatis.c:\belajarjava.lyracc.com\KopiFile\src\KopiFile.java
ke c:\belajarjava.lyracc.com\Kopi123.java
.