Dữ liệu được lưu trữ trong các biến và mảng là tạm thời, nó bị mất khi một biến cục bộ bị mất phạm vi hoặc khi chương trình kết thúc. Để lưu giữ dữ liệu lâu dài, ngay cả sau khi chương trình kết thúc, máy tính sử dụng tập tin (file). Máy tính lưu trữ file trên các thiết bị lưu trữ thứ cấp như đĩa cứng, USB, địa CD,…
Hình 4. 1 Kích thước file n byte
Java xem mỗi tệp như một luồng byte liên tiếp (Hình 4.1). Mỗi hệ điều hành cung cấp một cơ chế để xác định kết thúc của một tệp, chẳng hạn như điểm đánh dấu cuối tệp hoặc số đếm trong tổng số byte trong tệp được ghi lại trong cấu trúc file. Một chương trình Java xử lý một luồng byte chỉ đơn giản là nhận dữ liệu từ hệ điều hành khi đến cuối luồng thì chương trình dừng mà không cần để biết file hoặc luồng được biểu diễn như thế nào.
Các luồng dữ liệu được biểu diễn bằng chuỗi nhị phân định dạng theo byte (byte
based stream) hoặc chuỗi các ký tự (character stream). Ví dụ, số 5 nếu được lưu
dưới dạng nhị phân sẽ là 0000.0101. Nếu số 5 được lưu dưới dạng ký tự thì nó sẽ là các số nhị phân biểu diễn giá trị mã Unicode dùng để mô tả ký tự 5. Cụ thể, ký tự 5 trong bảng mã Unicode có mã là 53. Vì vậy, chuỗi số nhị phân được lưu vào file sẽ là 0000.0000.0011.0101. Sự khác biệt giữa hai cách lưu số 5 này là trong cách thứ nhất, 5 được hiểu là một số nguyên và có thể đọc ra để tính toán còn trong cách thứ hai, 5 được hiểu là ký tự và được sử dụng trong các chuỗi. Ví dụ ‘‘Tom is 5 years old’’. Các file sử dụng luồng nhị phân được gọi là file nhị phân (binary file), còn các file sử dụng luồng ký tự được gọi là file văn bản (text file). File văn bản có thể được đọc bởi các chương trình soạn thảo văn bản, trong khi file nhị phân chỉ có thể đọc bởi các chương trình có thể hiểu được cấu trúc file đó.
Chương trình Java mở file bằng cách tạo ra một đối tượng, sau đó đối tượng đó được kết hợp với một luồng byte hoặc luồng ký tự. Chương trình Java xử lý file bằng cách sử dụng các lớp trong gói Java.io. Gói này cung cấp các lớp xử lý luồng dữ liệu như
FileInputStream (dùng để ghi luồng byte vào một file), FileOutputStream (dùng để đọc luồng byte từ một file) và FileWriter (dùng để ghi luồng ký tự vào file) và FileReader (dùng để đọc luồng ký tự từ file) được kế thừa từ các lớp InputStream,
OutputStream, Reader và Writer tương ứng.
1 2 3 4 5 6 ... n
68
Java cũng cung cấp các lớp dùng để xử lý dữ liệu vào/ra là các đối tượng hoặc các dữ liệu cơ bản. Các dữ liệu này về bản chất vẫn được lưu dưới dạng byte hoặc ký tự nhưng đối với người lập trình chúng ta có thể đọc dữ liệu dưới dạng cơ bản int, float,… hoặc String mà không cần quan tâm chúng được chuyển sang dạng byte hoặc dạng ký tự như thế nào. Để xử lý các dữ liệu này, đối tượng của các lớp ObjectInputStream và
ObjecOutputStream được dùng cùng với các lớp luồng byte FileInputStream và
FileOutputStream.