1. InputStreamReader
lớp học
Một tính năng thú vị khác của các luồng là bạn có thể kết hợp nhiều luồng lại với nhau thành chuỗi . Một luồng có thể đọc dữ liệu không chỉ từ nguồn dữ liệu nội bộ của nó mà còn từ một luồng khác .
Đây là một cơ chế rất mạnh trong Java, cho phép tạo các tình huống đọc dữ liệu phức tạp bằng cách kết nối luồng này với luồng khác. Một kế hoạch như vậy trông như thế này:
Khi một chương trình đọc dữ liệu từ một luồng dữ liệu, luồng dữ liệu sẽ đọc dữ liệu từ nguồn dữ liệu của nó, chẳng hạn như một luồng dữ liệu khác hoặc một tệp.
Hơn nữa, mỗi luồng dữ liệu không chỉ đọc và đưa ra dữ liệu mà còn có thể biến đổi hoặc thực hiện các thao tác khác nhau trên đó. Một ví dụ điển hình về "luồng trung gian" như vậy là lớp InputStreamReader
học.
Chúng tôi đã biết một lớp được gọi là FileReader
- đó là lớp Reader
đọc dữ liệu từ một tệp. Và lấy dữ liệu của nó từ đâu InputStreamReader
? Đúng vậy - từ một tệp InputStream
.
Khi bạn tạo một InputStreamReader
đối tượng, bạn cần truyền vào một InputStream
đối tượng hoặc một trong các lớp con của nó. Ví dụ:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
Lớp này InputStreamReader
có tất cả các phương thức mà Reader
lớp đó có và chúng hoạt động theo cùng một cách.
Sự khác biệt chính giữa InputStreamReader
lớp và, giả sử, FileReader
là nơi họ đọc dữ liệu từ đó. FileReader
đọc dữ liệu từ một tệp (duh - đó là lý do tại sao nó được gọi là FileReader
), nhưng InputStreamReader
đọc dữ liệu từ tệp InputStream
.
Khi bạn đọc một ký tự từ một FileReader
đối tượng bằng read()
phương thức này, nó sẽ lần lượt đọc hai byte từ tệp trên đĩa và trả về chúng dưới dạng chars
.
Khi bạn đọc một ký tự từ một InputStreamReader
đối tượng bằng read()
phương thức này, nó sẽ lần lượt đọc hai byte từ FileInputStream
đối tượng được truyền cho nó, từ đó đọc dữ liệu từ tệp. Kết quả là một chuỗi các cuộc gọi đến read()
các phương thức.
2. BufferedReader
lớp học
Một lớp thú vị khác mà bạn có thể sẽ sử dụng nhiều là BufferedReader
. Đây cũng là một "luồng trung gian" đọc dữ liệu từ một luồng khác.
Như tên gọi của nó, BufferedReader
lớp này là một lớp con của Reader
và cho phép bạn đọc các ký tự . Nhưng điều thú vị nhất là bạn cũng cần truyền cho nó một nguồn dữ liệu ở dạng luồng mà các ký tự có thể được đọc từ đó , tức là luồng kế thừa Reader
lớp.
Vấn đề ở đây là gì? Không giống như InputStreamReader
, BufferedReader
lớp không chuyển đổi byte thành ký tự: nó hoàn toàn không chuyển đổi bất kỳ thứ gì. Thay vào đó, nó đệm dữ liệu .
Khi một chương trình đọc một ký tự đơn từ một BufferedReader
đối tượng, đối tượng đó sẽ đọc một mảng lớn các ký tự từ luồng nguồn của nó cùng một lúc. Và lưu trữ chúng trong nội bộ.
Khi ký tự tiếp theo được đọc từ BufferedReader
đối tượng, nó chỉ cần lấy ký tự tiếp theo từ mảng bộ đệm bên trong của nó và trả về ký tự đó mà không cần truy cập nguồn dữ liệu. Chỉ khi tất cả các ký tự trong bộ đệm được sử dụng hết thì nó mới đọc trong một mảng ký tự lớn khác.
Lớp này BufferedReader
cũng có một phương thức rất hữu ích — String readLine()
, cho phép bạn đọc toàn bộ chuỗi dữ liệu từ luồng nguồn cùng một lúc. Bạn có thể sử dụng phương pháp này để đọc một tệp và hiển thị nội dung của nó trên màn hình theo từng dòng. Ví dụ:
Chúng tôi đã viết cụ thể một số mã nhỏ gọn để minh họa mức độ thuận tiện của điều này. Mã này cũng có thể được viết chi tiết hơn một chút.
|
Tạo một FileReader đối tượng. Nguồn dữ liệu là một tập tin. Tạo một BufferedReader đối tượng. Nguồn dữ liệu là một tệp FileReader . Miễn là vẫn còn dữ liệu trong đầu đọc Đọc một dòng Hiển thị dòng |
Nếu bạn xâu chuỗi nhiều luồng lại với nhau, thì close()
phương thức chỉ cần được gọi trên một trong số chúng. Luồng đó sẽ gọi phương thức trên nguồn dữ liệu của nó, v.v. cho đến khi close()
được gọi trên luồng dữ liệu cuối cùng.
3. Đọc từ bảng điều khiển
Và một sự thật thú vị nữa: Scanner
lớp không gì khác hơn là một luồng đầu vào trung gian đọc dữ liệu từ System.in
, cũng là một luồng dữ liệu.
Đây là hai cách để đọc một dòng từ bảng điều khiển:
lớp máy quét | Các lớp BufferedReader và BufferedWriter |
---|---|
|
|
Bạn của chúng ta không gì khác hơn là một biến tĩnh của lớp. Đó là một người có tên là .System.in
in
System
InputStream
in
Vì vậy, gần như ngay từ khi bắt đầu học Java trên CodeGym, bạn đã làm việc với các luồng dữ liệu và xây dựng các chuỗi từ chúng. Nhưng bây giờ bạn sẽ làm điều đó một cách có ý thức hơn.
GO TO FULL VERSION