Khái niệm
Dòng bộ đệm
Nhập/xuất với tập tin
Tuần tự hóa
Giới thiệu
Dòng (stream) là một sự biểu diễn trừu tượng
dữ liệu được kết nối với một số thiết bị vào
Java Stream
Hỗ trợ sẵn bộ đệm tự động (buffering)
Hỗ trợ sự biểu diễn của các dòng sử
dụng sự trừu tượng hóa mức cao (khác
với bytes)
◦ Đọc/ghi các kiểu dữ liệu đơn nguyên
◦ Đọc/ghi các đối tượng
◦ Định dạng sẵn các dòng ký tự bao gồm sự
chuyển đổi qua lại với các biểu diễn khác
(như int, double,…)
27 trang |
Chia sẻ: candy98 | Lượt xem: 508 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Bài giảng Lập trình Java - Chương 6: Các dòng nhập/ xuất - Lăng Uy Tín, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Các dòng nhập/xuất
(Input/Output Streams)
Nội dung
Khái niệm
Dòng bộ đệm
Nhập/xuất với tập tin
Tuần tự hóa
Giới thiệu
Dòng (stream) là một sự biểu diễn trừu tượng
dữ liệu được kết nối với một số thiết bị vào
hay ra
Java Stream
Hỗ trợ sẵn bộ đệm tự động (buffering)
Hỗ trợ sự biểu diễn của các dòng sử
dụng sự trừu tượng hóa mức cao (khác
với bytes)
◦ Đọc/ghi các kiểu dữ liệu đơn nguyên
◦ Đọc/ghi các đối tượng
◦ Định dạng sẵn các dòng ký tự bao gồm sự
chuyển đổi qua lại với các biểu diễn khác
(như int, double,)
Các lớp stream cơ bản
Các lớp stream chính ở trong gói java.io.*
Hai lớp trừu tượng chính
◦ InputStream
int read()
int read(byte[] b)
int read(byte[] b, int off, int len)
◦ OutputStream
void write(int b)
void write(byte[] b)
void write(byte[] b, int off, int len)
Cung cấp chức năng cơ bản cho việc đọc dữ
liệu đến một luồng theo dạng các byte thô
InputStream và OutputStream
Nhiều lớp dẫn xuất tồn tại để cung cấp
các chức năng chuyên dụng.
Các lớp dẫn xuất đáng chú ý:
◦ FileInputStream, FileOutputStream
◦ BufferedInputStream, BufferedOutputStream
◦ ObjectInputStream, ObjectOutputStream
◦ PrintStream
Và còn nhiều hơn
Ví dụ: FileInputStream
Ví dụ chương trình đọc dữ liệu từ một tập tin theo
từng byte (đọc một byte tại một thời điểm).
Các dòng bộ đệm
Ví dụ trước không có hiệu quả bởi vì nó
đọc trực tiếp từ file một byte tại một
thời điểm chậm
Chúng ta có thể dùng lớp
BufferedInputStream bao bọc lớp
FileInputStream để đọc khối dữ liệu lớn
hơn và lưu giữ trong một bộ đệm sử
dụng cho việc đọc.
Các dòng bộ đệm
File
FileInputStream
BufferedInputStream
Java Program
{
}
BufferedInputStream đọc dữ
liệu từ file trong các khối lớn
và lưu giữ dữ liệu trong một
bộ đệm bên trong
Bộ đệm
Sau đó, bạn có thể đọc dữ liệu
từ BufferedInputStream và dữ
liệu được đọc từ bộ đệm thay vì
trực tiếp từ file trên mỗi lần đọc
Ví dụ: BufferedInputStream
Ví dụ sử dụng lớp BufferedInputStream bao
bọc lớp FileInputStream để đọc dữ liệu từ file:
Các dòng ký tự
Thông thường, các thiết bị vào/ra kết hợp với
một dòng được biểu diễn như một dãy các ký
tự.
◦ Những tập tin văn bản, dữ liệu vào bằng bàn phím,
đầu ra cuối,
Việc xử lý trực tiếp với các byte thô của dữ
liệu khi muốn làm việc với văn bản trong Java
theo định dạng Unicode là rất khó khăn
Hai lớp trừu tượng chính để giải quyết điều
này
◦ Reader
◦ Writer
Reader và Writer
Giống như các lớp InputStream và OutputStream, các
lớp Reader và Writer cũng có nhiều lớp dẫn xuất
Đáng chú ý InputStreamReader
◦ Dùng làm lớp bao bọc cho các đối tượng InputStream.
◦ Chuyển đổi các byte thô khi chúng được đọc từ InputStream
thành các ký tự Unicode.
◦ Ví dụ:
FileInputStream fs = new FileInputStream(“Employee.dat”)
InputStreamReader inp = new InputStreamReader (fs));
Thường dùng BufferedReader
◦ Dùng làm lớp bao bọc cho lớp InputStreamReader
◦ Ví dụ: BufferedReader kb = new BufferedReader( new
InputStreamReader(System.in));
Các dòng chuẩn
Java cung cấp sẵn các dòng cho đầu vào, đầu ra,
và lỗi chuẩn
◦ System.in (InputStream)
◦ System.out (PrintStream)
◦ System.err (PrintStream)
Hai đối tượng System.out và System.err có
kiểu PrintStream khá hữu ích cung cấp các cơ
chế để in các kiểu dữ liệu cơ sở cũng như
chuỗi vào dòng
System.in có kiểu InputStream là đối tượng
nhập chuẩn, thông thường chúng ta phải bao
bọc nó để dễ dàng sử dụng hơn
Đọc dữ liệu từ bàn phím
Như đã thấy, chúng ta có thể bao bọc lớp
InputStreamReader ngoài InputStream để làm cho
chúng trở nên hữu ích trong việc đọc dữ liệu ký tự
Sử dụng lớp bộ đệm BufferedReader cung cấp một
phương thức readLine() cho chức năng bổ sung.
StreamTokenizer
Lớp StreamTokenizer cung cấp chức năng
tương tự như StringTokenizer ngoại trừ
nó mạnh hơn và lấy dữ liệu của nó từ
một Reader thay vì một String
Theo mặc định nó đoán nhận các số,
chuỗi, từ, chú thích, và khoảng trắng như
các dấu hiệu (token)
Các dấu hiệu có thể được đọc một tại
một thời điểm và kiểu của chúng có thể
được xác định để xử lý chúng
Lớp File
Biểu diễn tên đường dẫn của một file
(pathname) mà file có thể có hay không
tồn tại.
Không thật sự đại diện cho chính file!
Cung cấp sự hỗ trợ cho các thao tác như
kiểm tra nếu một file/thư mục tồn tại, nó
là file hay thư mục, kiểm tra quyền truy
cập đọc/ghi, tạo và xóa file,
Dùng cho sự tạo các đối tượng dòng file
Lớp File
Các đối tượng File có thể được tạo cho cả các
file lẫn thư mục
Cũng hỗ trợ cho các dấu tách đường dẫn.
◦ Trên Unix tách đường dẫn là /, trong khi trên
Windows là \ (được biểu diễn \\).
◦ Tuy nhiên, cả hai dấu tách đều hợp lệ trên Windows.
Một số phương thức lớp File
exists() - kiểm tra file tồn tại
isDirectory() - kiểm tra file là một thư mục
isFile() - kiểm tra file thực sự là một file
isHidden() - kiểm tra file là ẩn
canRead() - kiểm tra file có thể được đọc bởi
người sử dụng hiện thời
canWrite() - kiểm tra file có thể được ghi bởi
người sử dụng hiện thời
getAbsolutePath() - trả lại đường dẫn tuyệt
đối
getAbsoluteFile() - trả lại một đối tượng File
Các dòng File
Các đối tượng File có thể được dùng tạo ra
các đối tượng dòng như FileInputStream,
FileOutputStream, FileReader, hay FileWriter.
Đơn giản cung cấp đối tượng File vào trong
một trong số những phương thức khởi tạo
thích hợp
Ví dụ:
Các dòng dữ liệu
Như đã thấy, cách xử lý các dòng có thể dòng
các byte hoặc dòng các ký tự
Đôi khi chúng ta muốn một mức độ trừu
tượng cao hơn và mong muốn đọc và ghi dữ
liệu tới các dòng theo dạng của các biến dữ
liệu đơn hay toàn bộ đối tượng lớp.
◦ Lưu thông tin trạng thái chương trình vào một file
◦ Gửi các biến dữ liệu cho các luồng (thread), các tiến
trình khác nhau hay gửi qua mạng
◦ Nhiều ví dụ khác
Java có sẵn các lớp dòng tự động kiểm soát
việc chuyển đổi thông tin này thành các byte
thô cần thiết
Các dòng dữ liệu
Java cung cấp hai lớp DataInputStream và
DataOutputStream tương ứng cho phép bạn đọc và ghi
các kiểu dữ liệu đơn nguyên tới các dòng vào/ra.
Lớp DataInputStream
◦ readByte()
◦ readChar()
◦ readDouble()
◦ readFloat()
◦ readInt()
◦
Lớp DataOutputStream có các phương thức write
tương ứng
Ví dụ
Dòng dữ liệu lớp
Thông thường, chương trình của chúng ta
không chỉ gồm có các kiểu dữ liệu đơn, chúng
ta cũng có thể muốn để đọc và ghi các lớp vào
các dòng
Java cung cấp hai lớp để thực hiện điều này là
ObjectInputStream và ObjectOutputStream.
Các lớp ObjectInputStream và
ObjectOutputStream cung cấp chức năng
tương tự như DataInputStream và
DataOutputStream, ngoại trừ chúng cũng có
hỗ trợ để đọc và ghi dữ liệu đối tượng thông
qua các phương thức readObject() và
writeObject().
Sự tuần tự hóa (Serialization)
Các đối tượng chỉ có thể được ghi vào một
dòng nếu chúng là một kiểu lớp mà hiện thực
giao tiếp Serializable.
Đa số các lớp có sẵn trong Java hiện thực giao
tiếp Serializable
Serializable không định nghĩa bất kỳ phương
thức nào. Vì thế, để tạo một lớp do người sử
dụng định nghĩa có khả năng được ghi vào một
dòng, thông thường bạn chỉ cần thêm
“implements Serializable” trong khai báo lớp.
Sự tuần tự hóa (Serialization)
Có quy định bắt buộc trong việc ghi các
đối tượng vào dòng đó là không chỉ lớp
cần hiện thực giao tiếp Serializable, mà
tất cả các thành viên của lớp cũng phải là
Serializable.
Nếu một thành viên của lớp Serializable,
nó có thể được khai báo transient và khi
đối tượng được ghi vào một dòng, thành
viên đó sẽ được ghi với giá trị null.
Tóm tắt
Bài Tập