Sử dụng luồng Byte

Như chúng ta đã biết hai lớp InputStream và OutputStream là hai siêu lớp (cha) đối với  tất cả những lớp luồ ng  xuất nhập kiểu byte. Những phương thức trong hai siêu lớp này ném ra các lỗi kiểu IOException. Những phương thức định nghĩa trong hai siêu lớp này là có thể dùng trong các lớp con của chúng. Vì vậy tập các phương thức đó là tập tối tiểu các chức năng nhập xuất mà những luồ ng nhập xuất kiểu byte có thể sử dụng.

Những phương thức định nghĩa trong lớp

1. Đọc dữ liệu từ Console

Trước đây, khi Java      mới  ra  đời  để  thực  hiện  việc nhập dữ liệu từ    Console  người  ta  chỉ dùng luồng   nhập byte.  Về  sau thì chúng ta có thể dùng cả luồ ng byte và luồ ng ký tự, nhưng trong một số trường hợp thực tế để đọc dữ liệu từ Console người ta thích dùng luồ ng kiểu ký tự hơn, vì lý do đơn giản và dễ bảo trì chương trình. Ở đây với mục đích minh họa chúng ta dùng luồ ng byte thực hiện việc nhập xuất Console.

Ví dụ: chương trình minh họa việc đọc một mảng bytes từ System.in

Import java.io. *;

class ReadBytes {

public static void main(String args[]) throws IOException

{

byte data[] = new byte[100]; System.out.print(“Enter some characters. “); System. in. read(data);

System.out.print(“You entered: “); for(int i=0; i < data.length; i++)

System. out.print((cchar) data[i]);

}

}

Kết quả:

2. Xuất dữ liệu ra Console

Tương tự     như nhập  dữ  liệu  từ  Console,  với  phiên bản  đầu tiên của java để xuất dữ liệu ra Console tả chỉ có thể sử dụng

luồ ng byte. Kể từ phiên bản 1.1 (có thêm luồ ng ký tự), để xuất dữ liệu ra Console có thể sử dụng cả luồ ng ký tự và luồ ng byte. Tuy nhiên, cho đến nay để xuất dữ liệu ra Console thường người ta vẫn dùng luồ ng byte.

Chúng ta đã khá quen thuộc với phương thức print() và println(), dùng để xuất dữ liệu ra Console. Bên cạnh đ1o chúng ta cũng có thể dùng phương thức write().

Ví dụ: minh họa sử dụng phương thức System.out.write() để xuất ký tự ‘X’ ra Console

import java.io. *; class WriteDemo {

public static void main(String args[])

{

int b; b = X’;

System. out. write (b);

System. out. write (r\nr);

}

Kết quả:

3. Đọc và ghi file dùng luồng Byte

int b; b = X’;

System. out. write (b);

System. out. write (r\nr);

Tạo một luồng Byte gắn với file chỉ định dùng FileInputStream và FileOutputStream. Để mở một file, đơn giản chỉ cần tạo một đối tượng của những lớp này, tên file cần mở là thông số trong constructor. Khi file mở, việc đọc và ghi dữ liệu trên file được thực hiện một cách bình thường thông qua các phương thức cung cấp trong luồng.

3.1 Đọc dữ liệu từ file

  • Mở một file để đọc dữ liệu FileInputStream(StringfileName) throws FileNotFoundException

Nếu file không tồn tại: thì ném ra FileNotFoundException

  • Đọc dữ liệu: dùng phương thức read()

int read() throws IOException: đọc từng byte từ file và trả về giá trị của byte đọc được. Trả về -1 khi hết file, và ném ra IOException khi có lỗi đọc.

  • Đóng file: dùng phương thức close()

void close() throws IOException: sau khi làm việc xong cần đóng file để giải phóng tài nguyên hệ thống đã cấp phát cho file.

Ví dụ:

/* ‘ ‘

Hiển thị nội dung của một file tên test.txt lưu tạiD:\test.txt */

import java.io. *; class ShowFile {

public static void main(String args[]) throws IOException {

int i;

FileInputStream fin; try {

fin = new FileInputStream(“D:\\test.txt”);

}

catch(FileNotFoundException exc)

{

System.out.println(“File Not Found”);

 

}

catch(ArrayIndexOutOfBoundsException exc)

{

System.out.println(“Usage: ShowFile File”); return;

}

// read bytes until EOF is encountered do {

i = fin.read();

if(i != -1) System.out.print((char) i);

} while(i != -1); fin.close();

}

Kết quả:

3.2.Ghi dữ liệu xuống file

  • Mở một file để ghi dữ liệu FileOutputStream(StringfileName) throws FileNotFoundException

Nếu file không tạo được: thì ném ra FileNotFoundException

  • Ghi dữ liệu xuống: dùng phương thức write()

void write(int byteval) throws IOException: ghi một byte xác định bởi tham số byteval xuống file, và ném ra IOException khi có lỗi ghi.

  • Đóng file: dùng phương thức close()

void close() throws IOException: sau khi làm việc xong cần đóng file để giải phóng tài nguyên hệ thống đã cấp phát cho file.

Ví dụ: copy nội dung một file text đến một file text khác.

/* Copy nội dung của một file text*/ import java.io. *; class CopyFile {

public static void main(String args[])throws IOException {

int i;

FileInputStream fin;

FileOutputStream fout; try {

// open input file try {

fin = new FileInputStream(“D:\\source.txt”);

}

catch(FileNotFoundException exc)

{

System.out.println(“Input File Not Found”); return;

}

// open output file try {

fout = new FileOutputStream(“D:\\dest.txt”);

}

catch(FileNotFoundException exc)

{

System.out.println(“Error Opening Output

File”);

return;

}

}

catch(ArrayIndexOutOfBoundsException exc)

{

System.out.println(“Usage: CopyFile From To”); return;

}

// Copy File try {

do

{

i = fin.read();

if(i != -1) fout.write(i);

} while(i != -1);

}

catch(IOException exc)

{

System. out.println(“File Error “);

}

fin.close();

fout.close();

}

}

Kết quả thực thi chương trình: chương trình sẽ copy nội dung của file D:\source.txt và ghi vào một file mới D:\dest.txt.

4. Đọc và ghi dữ liệu nhị phân

Phần trên chúng ta đã đọc và ghi các bytes dữ liệu là các ký tự mã ASCII. Để đọc và ghi những giá trị nhị phân của các kiểu dữ liệu trong java, chúng ta sử dụng DataInputStream và DataOutputStream.

DataOutputStream: hiện thực interface DataOuput. Interface DataOutput có các phương thức cho phép ghi tất cả những kiểu dữ liệu cơ sở của java đến luồ ng (theo định dạng nhị phân).

OutputStream: là luồng xuất dữ liệu. Để ghi dữ liệu ra file thì đối tượng outputStream có thể là FileOutputStream.

DataInputStream: hiện thực interface DataInput. Interface DataInput có các phương thức cho phép đọc tất cả những kiểu dữ liệu cơ sở của java (theo định dạng nhị phân).

Contructor: DataInputStream(InputStream inputStream)

InputStream: là luồng nhập dữ liệu. Để đọ dữ liệu từ file thì đối tượng InputStream có thể là FileInputStream.

Ví dụ: dùng DataOutputStream và DataInputStream để ghi và đọc những kiểu dữ liệu khác nhau trên file. import java.io. *; class RWData {

public static void main(String args[]) throws IOException {

DataOutputStream dataOut;

DataInputStream dataIn; int i = 10;

double d = 1023.56; boolean b = true; try {

dataOut = new DataOutputStream(

new FileOutputStream(“D:\ \testdata”));

}

catch(IOException exc) {

System.out.println(”Cannot open file. ”); return;

}

try

{

System.out.println(”Writing ” + i); dataOut. writeInt(i); System.out.println(”Writing ” + d); dataOut. writeDouble(d); System.out.println(”Writing ” + b); dataOut. writeBoolean(b); System.out.println(”Writing ” + 12.2 * 7.4); dataOut.writeDouble(12.2 * 7.4);

}

catch(IOException exc)

{

System.out.println(”Write error. ”);

}

dataOut. close ();

System. out.println();

// Now, read them back. try {

dataIn = new DataInputStream(

new FileInputStream(”D:\ \testdata”));

}

catch(IOException exc)

{

System.out.println(”Cannot open file. ”); return;

}

try

{

i = dataIn.readInt(); System.out.println(“Reading ” + i); d = dataIn.readDouble(); System.out.println(“Reading ” + d); b = dataIn.readBoolean(); System.out.println(“Reading ” + b); d = dataIn.readDouble(); System.out.println(“Reading ” + d);

}

catch(IOException exc)

{ System.out.println(“Readerror. “);

}

dataIn.close();

}

}