Tất cả những hoạt động nhập/xuất dữ liệu (nhập dữ liệu từ bàn phím, lấy dữ liệu từ mạng về, ghi dữ liệu ra đĩa, xuất dữ liệu ra màn hình, máy in, …) đều đƣợc quy về một khái niệm gọi là luồng (stream). Luồng là nơi có thể “sản xuất” và “tiêu thụ” thông tin. Luồng thƣờng đƣợc hệ thống xuất nhập trong java gắn kết với một thiết bị vật lý. Tất cả các luồng đều có chung một nguyên tắc hoạt động ngay cả khi chúng đƣợc gắn kết với các thiết bị vật lý khác nhau. Vì vậy cùng một lớp, phƣơng thức xuất nhập có thể dùng chung cho các thiết bị vật lý khác nhau. Chẳng hạn cùng một phƣơng thức có thể dùng để ghi dữ liệu ra console, đồng thời cũng có thể dùng để ghi dữ liệu xuống một file trên đĩa. Java hiện thực luồng bằng tập hợp các lớp phân cấp trong gói java.io.
Java định nghĩa hai kiểu luồng: byte và ký tự (phiên bản gốc chỉ định nghĩa kiểu luồng byte, và sau đó luồng ký tự đƣợc thêm vào trong các phiên bản về sau). Luồng byte (hay luồng dựa trên byte) hỗ trợ việc xuất nhập dữ liệu trên byte, thƣờng đƣợc dùng khi đọc ghi dữ liệu nhị phân. Luồng ký tự đƣợc thiết kế hỗ trợ việc xuất nhập dữ liệu kiểu ký tự (Unicode). Trong một vài trƣờng hợp luồng ký tự sử dụng hiệu quả hơn luồng byte, nhƣng ở mức hệ thống thì tất cả những xuất nhập đều phải qui về byte. Luồng ký tự hỗ trợ hiệu quả chỉ đối với việc quản lý, xử lý các ký tự.
Các luồng byte đƣợc định nghĩa dùng hai lớp phân cấp. Mức trên cùng là hai lớp trừu tƣợng InputStream và OutputStream. InputStream định nghĩa những đặc điểm chung cho những luồng nhập byte. OutputStream mô tả cách xử lý của các luồng xuất byte.
Các lớp con dẫn xuất từ hai lớp InputStream và OutputStream sẽ hỗ trợ chi tiết tƣơng ứng với việc đọc ghi dữ liệu trên những thiết bị khác nhau. Đừng choáng ngợp với hang loạt rất nhiều các lớp khác nhau. Đừng quá lo lắng, mỗi khi bạn nắm vững, sử dụng thành thạo một luồng byte nào đó thì bạn dễ dàng làm việc với những luồng còn lại.
Lớp luồng byte Ý nghĩa
BufferedInputStream Buffered input stream BufferedOutputStream Buffered output stream
ByteArrayInputStream Input stream đọc dữ liệu từ một mảng byte ByteArrayOutputStream Output stream ghi dữ liệu đến một mảng byte
DataInputStream Luồng nhập có những phƣơng thức đọc những kiểu dữ liệu chuẩn trong java
DataOutputStream Luồng xuất có những phƣơng thức ghi những kiểu dữ liệu chuẩn trong java
FileInputStream Luồng nhập cho phép đọc dữ liệu từ file FileOutputStream Luồng xuất cho phép ghi dữ liệu xuống file FilterInputStream Hiện thực lớp trừu tƣợng InputStream FilterOutputStream Hiện thực lớp trừu tƣợng OutputStream
InputStream Lớp trừu tƣợng, là lớp cha của tất cả các lớp luồng nhập kiểu Byte
OutputStream Lớp trừu tƣợng, là lớp cha của tất cả các lớp xuất nhập kiểu Byte
PipedInputStream Luồng nhập byte kiểu ống (piped) thƣờng phải đƣợc gắn với một luồng
PipedOutputStream Luồng nhập byte kiểu ống (piped) thƣờng phải đƣợc gắn với một luồng nhập kiểu ống để tạo nên một kết nối trao đổi dữ liệu kiểu ống.
PrintStream Luồng xuất có chứa phƣơng thức print() và println()
PushbackInputStream Là một luồng nhập kiểu Byte mà hỗ trợ thao tác trả lại (push back) và phục hồi thao tác đọc một byte (unread)
RandomAccessFile Hỗ trợ các thao tác đọc, ghi đối với file truy cập ngẫu nhiên. SequenceInputStream Là một luồng nhập đƣợc tạo nên bằng cách nối kết logic các
luồng nhập khác.
Các luồng ký tự đƣợc định nghĩa dùng hai lớp phân cấp. Mức trên cùng là hai lớp trừu tƣợng Reader và Writer. Lớp Reader dùng cho việc nhập dữ liệu của luồng, lớp Writer dùng cho việc xuất dữ liệu cua luồng. Những lớp dẫn xuất từ Reader và Writer thao tác trên các luồng ký tự Unicode.
Lớp luồng ký tự Ý nghĩa
BufferedReader Luồng nhập ký tự đọc dữ liệu vào một vùng đệm. BufferedWriter Luồng xuất ký tự ghi dữ liệu tới một vùng đệm. CharArrayReader Luồng nhập đọc dữ liệu từ một mảng ký tự CharArrayWriter Luồng xuất ghi dữ liệu tời một mảng ký tự FileReader Luồng nhập ký tự đọc dữ liệu từ file FileWriter Luồng xuất ký tự ghi dữ liệu đến file
FilterReader Lớp đọc dữ liệu trung gian (lớp trừu tƣợng) FilterWriter Lớp xuất trung gian trừu tƣợng
InputStreamReader Luồng nhập chuyển bytes thành các ký tự LineNumberReader Luồng nhập đếm dòng
OutputStreamWriter Luồng xuất chuyển những ký tự thành các bytes PipedReader Luồng đọc dữ liệu bằng cơ chế đƣờng ống PipedWriter Luồng ghi dữ liệu bằng cơ chế đƣờng ống
PrintWriter Luồng ghi văn bản ra thiết bị xuất (chứa phƣơng thức print() và println() )
PushbackReader Luồng nhập cho phép đọc và khôi phục lại dữ liệu
Reader Lớp nhập dữ liệu trừu tƣợng
StringReader Luồng nhập đọc dữ liệu từ chuỗi StringWriter Luồng xuất ghi dữ liệu ra chuỗi
Writer Lớp ghi dữ liệu trừu tƣợng
8.7.3. Những luồng đƣợc định nghĩa trƣớc (The Predefined Streams)
Tất cả các chƣơng trình viết bằng java luôn tự động import gói java.lang. Gói này có định nghĩa lớp System, bao gồm một số đặc điểm của môi trƣờng run-time, nó có ba biến luồng đƣợc định nghĩa trƣớc là in, out và err, các biến này là các fields đƣợc khai báo static trong lớp System.
g. System.out: luồng xuất chuẩn, mặc định là console. System.out là một đối tƣợng kiểu PrintStream. h. System.in: luồng nhập chuẩn, mặc định là bàn phím.
System.in là một đối tƣợng kiểu InputStream. i. System.err: luồng lỗi chuẩn, mặc định cũng là console.
8.7.4. 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 InputStream và OutputStream
Phƣơng thức Ý nghĩa
InputStream int available( ) Trả về số luợng bytes có thể đọc đƣợc từ luồng nhập
void close( ) Đóng luồng nhập và giải phóng tài nguyên hệ thống gắn với luồng. Không thành công sẽ ném ra một lỗi IOException void mark(int numBytes) Đánh dấu ở vị trí hiện tại trong luồng nhập
boolean markSupported( ) Kiểm tra xem luồng nhập có hỗ trợ phƣơng thức mark() và reset() không.
int read( ) Đọc byte tiếp theo từ luồng nhập
int read(byte buffer[ ]) Đọc buffer.length bytes và lƣu vào trong vùng nhớ buffer. Kết quả trả về số bytes thật sự đọc đƣợc
int read(byte buffer[ ], int offset, int numBytes)
Đọc numBytes bytes bắt đầu từ địa chỉ offset và lƣu vào trong vùng nhớ buffer. Kết quả trả về số bytes thật sự đọc đƣợc
void reset( ) Nhảy con trỏ đến vị trí đƣợc xác định bởi việc gọi hàm mark() lần sau cùng.
long skip(long numBytes) Nhảy qua numBytes dữ liệu từ luồng nhập OutputStream void close( ) Đóng luồng xuất và giải phóng tài nguyên hệ thống gắn với
luồng. Không thành công sẽ ném ra một lỗi IOException void flush( ) Ép dữ liệu từ bộ đệm phải ghi ngay xuống luồng (nếu có) void write(int b) Ghi byte dữ liệu chỉ định xuống luồng
void write(byte buffer[ ]) Ghi buffer.length bytes dữ liệu từ mảng chỉ định xuống luồng
void write(byte buffer[ ], int offset, int numBytes)
Ghi numBytes bytes dữ liệu từ vị trí offset của mảng chỉ định buffer xuống luồng là thƣ mục không?
public boolean isFile() Kiểm tra xem tập tn có phải là một file không? …
public String[] list() Lấy danh sách tên các tập tin và thƣ mục con của đối tƣợng File đang xét và trả về trong một mảng.
Ví dụ:
import java.awt.*; import java.io.*; public class FileDemo {
public static void main(String args[]) {
Frame fr = new Frame ("File Demo"); fr.setBounds(10, 10, 300, 200); fr.setLayout(new BorderLayout());
Panel p = new Panel(new GridLayout(1,2)); List list_C = new List();
list_C.add("C:\\");
File driver_C = new File ("C:\\"); String[] dirs_C = driver_C.list(); for (int i=0;i<dirs_C.length;i++) { File f = new File ("C:\\" + dirs_C[i]); if (f.isDirectory())
list_C.add("<DIR>" + dirs_C[i]); else
list_C.add(" " + dirs_C[i]); }
List list_D = new List(); list_D.add("D:\\");
File driver_D = new File ("D:\\"); String[] dirs_D = driver_D.list(); for (int i=0;i<dirs_D.length;i++) { File f = new File ("D:\\" + dirs_D[i]); if (f.isDirectory()) list_D.add("<DIR>" + dirs_D[i]); else list_D.add(" " + dirs_D[i]); } p.add(list_C); p.add(list_D); fr.add(p, BorderLayout.CENTER); fr.setVisible(true); } } Kết quả
Bài Tập
1. Thiết kế các thành phần và các hành động khi một khách hàng thực hiện một giao dịch ATM (Automatic Teller Machine).
2. Liệt kê những thuộc tính và những phƣơng thức cần có để vẽ một hình đa giác. 3. Hãy viết một đoạn chƣơng trình để in ra dòng chữ ” Welcome to the world of Java” 4. Hãy viết hai phƣơng thức khởi tạo tƣờng minh cho một lớp dùng để tính diện tích
hình chữ nhật. Khi một giá trị đƣợc truyền vào phƣơng thức khởi tạo, nó cho rằng độ dài và chiều rộng bằng nhau và bằng giá trị truyền vào. Lúc đó, nó sẽ tính diện tích tƣơng ứng. Khi hai giá trị đƣợc truyền vào, nó sẽ tính diện tích hình chữ nhật. 5. Viết một chƣơng trình thực hiện những việc sau đây:
a. Khai báo và gán giá trị đầu cho các biến m và n là 100 và 200 tƣơng ứng. b. Theo các điều kiện: nếu m bằng 0, hiển thị kết quả tƣơng ứng.
c. Nếu m lớn hơn n , hiển thị kết quả tƣơng ứng. d. Kiểm tra giá trị n là chẵn hay lẻ.
6. Viết một chƣơng trình hiển thị tổng các bội số của 7 nằm giữa 1 và 100. 7. Viết chƣơng trình để cộng bảy số hạng của dãy sau:
1!+2!+3!……….
8. Viết chƣơng trình thực hiện các yêu cầu sau:
a. Tạo một lớp điểm biểu diễn một điểm trong không gian bao gồm các thuộc tính - Hoành độ
- Tung độ - Cao độ
b. Bổ sung các phƣơng thức sau cho lớp
- Phƣơng thức khởi tạo không có tham số nào.
- Phƣơng thức khởi tạo nhận 3 tham số thực làm tham số
- Phƣơng thức nhập vào một điểm từ bàn phím
- Phƣơng thức in thông tin một điểm ra màn hình
c. Viết phƣơng thức Main kiểm tra các phƣơng thức đã cài đặt cho lớp
Hướng dẫn:Tọa độ của một điểm có kiểu giá trị là float
9. Xây dựng lớp Stack để mô phỏng một Stack bao gồm: - Hàm tạo Stack(int n) để khởi tạo Stack có tối đa n phần tử
- Phƣơng thức isFull để kiểm tra xem Stack đã đầy hay chƣa?
- Phƣơng thức push để thêm một phần tử vào Stack
- Phƣơng thức pop để lấy một phần tử ra khỏi Stack
10. Xây dựng lớp MaTran cho để thực hiện các phép toán trên ma trận, bao gồm: - Hàm tạo ma MaTran(int sh, int sc) dùng để khởi tạo một ma trận có số hàng là sh và số cột là sc.
- Phƣơng thức “print” để in ma trận ra màn hình - Phƣơng thức “nhap” để nhập ma trận từ bàn phím - Phƣơng thức “cong” để cộng hai ma trận
- Phƣơng thức “hieu” để thực hiện phép hiệu hai ma trận - Phƣơng thức “doiDau” để đổi dấu các phần tử của ma trận - Phƣơng thức main để kiểm tra ma trận trên
11. Xây dựng Project
a.Tạo một lớp biểu diễn phân số (có tử và mẫu là các số nguyên) gồm các thuộc tính
- Tử số
- Mẫu số
b. Bổ sung các phƣơng thức sau cho lớp.
- Phƣơng thức khởi tạo không có tham số nào, tạo phân số bằng 0.
- Phƣơng thức khởi tạo nhận 2 số nguyên làm tham số.
- Phƣơng thức khởi tạo nhận một đối tƣợng thuộc chính lớp này làm tham số.
- Phƣơng thức cộng, trừ, nhân, chia phân số này với một phân số khác.
- Phƣơng thức in phân số ra màn hình.
- Phƣơng thức rút gọn phân số
3. Viết hàm main kiểm tra các phƣơng thức đã tạo.
Hướng dẫn:
- Để tạo phân số bằng 0: tử số =0, mẫu số =1 - Rút gọn phân số
+ Tìm USCLN của tử số và mẫu số + tuso = tuso/ USCLN
private int USCLN(int a, int b){ while(a != b){ if(a > b) a = a-b; if(a < b) b = b-a; } return a; } 12. Xây dựng lớp Queue
- Hàm tạo Queue(int n) để khởi tạo Queue có tối đa n phần tử
- Phƣơng thức isEmpty để kiểm tra xem Queue có phần tử nào hay không? - Phƣơng thức isFull để kiểm tra xem Queue đã đầy hay chƣa?
- Phƣơng thức push để thêm một phần tử vào Queue. - Phƣơng thức popđể lấy một phần tử ra khỏi Queue.
13. Xây dựng một lớp biểu diễn đường tròn gồm có các thuộc tính: - Bán kính Bổ sung các phƣơng thức sau cho lớp:
- Phƣơng thức khởi tạo không có tham số nào.
- Phƣơng thức khởi tạo nhận một đối số thực làm tham số.
- Phƣơng thức khởi tạo nhận một đối tƣợng của chính lớp này làm tham số. - Phƣơng thức tinhChuVi() để tính chu vi của hình tròn.
- Phƣơng thức tinhDienTich() để tính diện tích của hình tròn. - Phƣơng thức Nhập() cho phép nhập bán kính .
- Phƣơng thức in() để in bán kính, chu vi và diện tích của hình tròn ra màn hình. - Thêm thuộc tính Bán kính vào lớp HinhTron vừa tạo ra ở trên.
-Xõy dựng lớp test để kiểm tra lớp vừa tạo
14. Xây dựng lớp hình trụ với thuộc tính gồm bán kính hình tròn, chiều cao hình trụ và các phƣơng thức thiết lập. Sau đó tính chu vi, diện tích xung quanh, diện tích toàn phần và thể tích của hình trụ đó.
Xây dựng lớp test thực hiện: Nhập các thông tin cho hình trụ từ bàn phím, hiển thị các thông tin về kích thƣớc, chu vi, diện tích của hình trụ ra màn hình.
15. Xây dựng lớp Hình Chữ Nhật bao gồm các thành phần:
- Chiều rộng.
- Hai thuộc tính chỉ đọc là Chu vi và Diện tích.
- Hai thuộc tính bao gồm cả đọc/ghi là Chiều dài và Chiều rộng. Bổ sung các phƣơng thức sau cho lớp:
- Phƣơng thức khởi tạo gồm có hai tham số. - Phƣơng thức khởi tạo không có tham số nào. Xây dựng lớp test để kiểm tra lớp vừa tạo
16. Xây dựng lớp Hình Vuông bao gồm các thành phần: cạnh.
- Hai thuộc tính chỉ đọc là Chu vi và Diện tích. - Thuộc tính bao gồm cả đọc/ghi là Cạnh. Bổ sung các phƣơng thức sau cho lớp: - Phƣơng thức khởi tạo gồm có hai tham số. - Phƣơng thức khởi tạo không có tham số nào. Xây dựng lớp test để kiểm tra lớp vừa tạo
17. Xây dựng lớp MyMath gồm các phƣơng thức sau:
- Phƣơng thức tĩnh GiaiThua(int n) để tính giai thừa của một số nguyên N. - Phƣơng thức tĩnh Tong_n(int n) để tính tổng của N số tự nhiên đầu tiên - Phƣơng thức tĩnh Mu(float a, int b) để tính ab
- Phƣơng thức tĩnh Tich(float a, float b) để tính tích a*b.
- Phƣơng thức tĩnh Thuong(float a, float b) để tính thơng của hai số a/b với b khác 0. Xây dựng lớp test để kiểm tra lớp vừa tạo.
18. Cho một dãy các hình chữ nhật. Bằng lập trình hƣớng đối tƣợng, hãy viết chƣơng trình thực hiện cỏc chức năng sau:
- Nhập vào một dãy hình chữ nhật
- Tìm và in ra hình chữ nhật có chu vi lớn nhất và hình chữ nhật cú diện tích lớn nhất
Hướng dẫn: Xây dựng lớp HCN có hai thuộc tính chỉ đọc là chiều dài và chiều rộng. 19. Xây dựng lớp ma trận gồm cú các phƣơng thức sau:
- Phƣơng thức khởi tạo khụng có tham số: khởi tạo kích thƣớc ma trận 2 x 2
- Phƣơng thức khởi tạo có hai tham số là hai số nguyên: số hàng, số cột của ma trận. - Phƣơng thức khởi tạo lấy chính đối tƣợng của lớp ma trận làm tham số.
- Nhập: cho phép nhập vào các phần tử của ma trận
- Cộng(int n): Cộng n vào giỏ trị của tất cả cỏc phần tử của ma trận - Cộng(Matran mt): Cộng hai ma trận có cùng kích thƣớc
- trừ(int n): trừ giỏ trị của tất cả các phần tử đi n đơn vị - trừ(Matran mt): Trừ hai ma trận có cùng kích thƣớc
Hướng dẫn:Ma trận cú 3 thành phần dữ liệu: số hàng, số cột, mảng hai chiều lƣu trữ cỏc phần tử của ma trận.
20. Xây dựng dự án
1) Xây dựng lớp Person gồm có các thành phần sau: