Xem mẫu

LUỒNG I/O Mục tiêu của môn học Kết thúc chương, bạn có có thể : Đề cập đến các khái niệm về luồng Mô tả các lớp InputStream và OutputStream Mô tả I/O mảng Byte Thực hiện các tác vụ đệm I/O và lọc Dùng lớp RandomAccesFile. Mô tả các tác vụ chuỗi I/O và ký tự Dùng lớp PrinterWriter 9.1 Giới thiệu Trong buổi học trước, chúng ta đã học về các dòng Synchronized. ngăn các dòng xẩy ra việc chia sẽ (dùng chung) các đối tượng một cách đồng thời. Toàn bộ tiến trình này được quản lý bởi cơ chế đợi thông báo (wait-notify). Phương thức wait() báo cho dòng gọi từ bỏ monitor và nhập vào trạng thái ngủ cho đến khi các dòng khác nhập vào cùng monitor và gọi phương thức notify(). Phương thức notify() và notifyAll() tạo ra dòng thông báo cho các dòng khác gọi phương thức wait() của cùng đối tượng. Trong bài học trước, chúng ta cũng học về các điều kiện bế tắc là gì và cách tránh chúng. Chương này giới thiệu khái niệm về luồng. Chúng ta cũng thảo luận các lớp khác nhau trong gói java.io trợ giúp các tác vụ nhập xuất. 9.2 Các luồng Theo thuật ngữ chung, luồng là một dòng lưu chuyển. trong thuật ngữ về kỹ thuật luồng là một lộ trình mà dữ liệu được truyền trong một chương trình. Một ứng dụng về các luồng ma ta đã quen thuộc đó là luồng nhập System.in . Luồng là những dàn ống (pipelines) để gửi và nhận thông tin trong các chương trình java. Khi một luồng dữ liệu được gửi hoặc nhân, ta tham chiếu nó như đang “ghi” và “đọc” một luồng theo thứ tự nêu trên. Khi một luồng được đọc hay ghi, các dòng khác bị phong toả. Nếu có một lỗi xẩy ra khi đọc hay ghi luồng, một IOexception được kích hoạt. Do vậy, các câu lệnh luồng phải bao gồm khối try-catch. Lớp ‘java.lang.System’ định nghĩa các luồng nhập và xuất chuẩn. chúng là các lớp chính của các luồng byte mà java cung cấp. Chúng ta cũng đã sử dụng các luồng xuất để xuất dữ liệu và hiển thị kết quả trên màn hình. Luồng I/O bao gồm: : Lớp System.out: Luồng xuất chuẩn dùng để hiển thị kết quả trên màn hình. Lớp System.in: Luồng nhập chuẩn thường đến từ bàn phím và được dùng để đọc các ký tự dữ liệu. Lớp System.err: Đây là luồng lỗi chuẩn. 65 Các lớp ‘InputStream’ và ‘OutputStream’ cung cấp nhiều khả năng I/O khác nhau. Cả hai lớp này có các lớp con để thực hiện I/O thông qua các vùng đệm bộ nhớ, các tập tin và ống dẫn. Các lớp con của lớp InputStream thực hiện đầu vào, trong khi các lớp con của lớp OutputStream thực hiện kết xuất. 9.3Gói java.io Các luồng hệ thống rất có ích. Tuy nhiên, chúng không đủ mạnh để dùng khi ứng phó với I/O thực tế. Gói java.io phải được nhập khẩu vì mục đích này. Chúng ta sẽ thảo luận tìm hiểu về các lớp thuộc gói java.io. 9.3.1 lớp InputStream Lớp InputStream là một lớp trừu tượng. Nó định nghĩa cách nhận dữ liệu. Điểm quan trọng không nằm ở chổ dữ liệu đế từ đâu, mà là nó có thể truy cập. Lớp InputStream cung cấp một số phương pháp để đọc và dùng các luồng dữ liệu để làm đầu vào. Các phương thức này giúp ta tạo, đọc và xử lý các luồng đầu vào. Các phương thức được hiện trong bản 9.1 Tên phương thức read() read (byte []) read (byte [], int, int) available() close() mark() markSupporte() reset() Mô tả Đọc các byte dữ liệu từ một luồng. Nếu như không dữ liệu nào là hợp lệ, nó khoá phương thức. Khi một phương thực được khoá, các dòng thực hiện được chờ cho đến khi dữ liệu hợp lệ. trả về byte được ‘đọc’ hay ‘-1’, nếu như kết thúc của một luồng đã đến. nó kích hoạt IOException nếu lỗi xảy ra. Nó cũng đọc vào mảng byte. Nó trả về số byte thực sự được đọc. Khi kết thúc của một luồng đã đến. nó kích hoạt IOException nếu lỗi xảy ra. Phương pháp này trả về số lượng byte có thể được đọc mà không bị phong toả. Nó trả về số byte hợp lệ. Nó không phải là phương thức hợp lệ đáng tin cậy để thực hiện tiến trình xử lý đầu vào. Phương thức này đóng luồng. Nó dùng để phóng thích mọi tài nguyên kết hợp với luồng. Luôn luôn đóng luồng để chắc chắn rằng luồng xử lý được kết thúc. Nó kích hoạt IOException nếu lỗi xảy ra. Đánh dấu vị trí hiện tại của luồng. trả về giá trị boolean nêu rõ luồng có hỗ trợ các khả năng mark và reset hay không. Nó trả về đúng nếu luồng hỗ trợ nó bằng không là sai. Phương thức này định vị lại luồng theo vị 66 trí được đánh dấu chót. Nó kích hoạt IOException nếu lỗi xảy ra. skip() Phương thức này bỏ qua ‘n’ byte đầu vào. ’-n’ chỉ định số byte được bỏ qua. Nó kích hoạt IOException nếu lỗi xảy ra. Phương thức này sử dụng để di chuyển tới vị trí đặc biệt bên trong luồng đầu vào. Table 9.1 InputStream Class Methods 9.3.2 Lớp OutputStream Lớp OutputStream cũng là lớp trừu tượng. Nó định nghĩa cách ghi các kết xuất đến luồng. Nó cung cấp tập các phương thức trợ giúp tạo ra, ghi và xử lý kết xuất các luồng. Các phương thức bao gồm: Tên phương thức write(int) write(byte[]) write(byte[],int,int) flush() close() Mô tả Phương thức này ghi một byte Phương thức này phong toả cho đến khi một byte được ghi. luồng chờ cho đến khi tác vụ ghi hoàn tất. Nó kích hoạt IOException nếu lỗi xảy ra. Phương thức này cũng ghi mảng các byte. Lớp OutputStream định nghĩa ba dạng quá tải của phương thức này để cho phép phương thức write() ghi một byte riêng lẻ, mảng các byte, hay một đoạn của một mảng. Phương thức này xả sạch luồng. đệm dữ liệu được ghi ra luồng kết xuất. Nó kích hoạt IOException nếu lỗi xảy ra. Phương thức đóng luồng. Nó được dùng để giải phóng mọi tài nguyên kết hợp với luồng. Nó kích hoạt IOException nếu lỗi xảy ra. Bảng 9.2 Các phương thức lớp OutputStream 9.3.3 Nhập và xuất mảng byte Các lớp ‘ByteArrayInputStream’ và ‘ByteArrayOutputStream’ sử dụng các đệm bộ nhớ. Không cần thiết phải dùng chúng với nhau. Lớp ByteArrayInputStream Lớp này tạo luồng đầu vào từ bộ nhớ đệm. Nó là mảng các byte. Lớp này không hỗ trợ các phương thức mới. Ngược lại nó chạy đè các phương thức của lớp InputStream như ‘read() ‘, ‘skip()’, ‘available()’ và ‘reset()’. Lớp ByteArrayOutputStream 67 Lớp này tạo ra luồng kết suất trên một mảng các byte. Nó cũng cung cấp các khả năng bổ sung để mảng kết suất tăng trưởng nhằm mục đích chừa chổ cho mảng được ghi. Lớp này cũng cung cấp các phương thức ‘toByteArrray()’ và ‘toString()’. Chúng được dùng để chuyển đổi luồng thành một mảng byte hay đối tượng chuỗi. Lớp ByteArrayOutputStream cũng cung cấp hai phương thức thiết lập. Một chấp nhận một đối số số nguyên dùng để ấn định mảng byte kết xuất theo một kích cỡ ban đầu. và thứ hai không chấp nhận đối số nào, và thiết lập đệm kết xuất với kích thước mặc định. lớp này cung cấp vài phương thức bổ sung, không được khai báo trong OutputStream: reset() Thiết lập lại kết xuất vùng đệm nhằm cho phép tiến trình ghi khởi động lại tại đầu vùng đệm. size() Trả về số byte hiện tại đã được ghi tới vùng đệm. writeto() Ghi nội dung của vùng đệm kết xuất ra luồng xuất đã chỉ định. Để thực hiện, nó chấp nhận một đối tượng của lớp OutputStream làm đối số. Chương trình 9.1 sử dụng lớp ‘ByteArrayInputStream’ và ‘ByteArrayOutputStream’ để nhập và xuất: Program 9.1 import java.lang.System; import jạva.io.*; public class byteexam { public static void main(String args[]) throws IOException { ByteArrayOutputStream os =new ByteArrayOutputStream(); String s ="Welcome to Byte Array Input Outputclasses"; for(int i=O; i