Chương 1: I/O và File 1. Một số cách thức vào/ra file với java.io chứa gần như tất cả các lớp bạn cần để thực hiện input và output (I/O) trong Java. Tất cả những stream này biểu diễn một nguồn input và một đích đến output. Stream trong java.io package hỗ trợ nhiều như liệu như các kiểu gốc, Object, các ký tự nội bộ, … Một stream có thể được định nghĩa như là một dãy liên tục dữ liệu.
InputStreamđược sử dụng để đọc dữ liệu từ một nguồn và OutputStream được sử dụng để ghi dữ liệu tới một đích đến. Java cung cấp sự hỗ trợ mạnh mẽ nhưng linh hoạt cho I/O liên quan tới các File và các mạng nhưng trong phần hướng dẫn này, chúng tôi chỉ bàn luận tính năng cơ bản liên quan tới các stream và I/O. Chúng ta sẽ xem xét từng ví dụ được sử dụng phổ biến nhất. Byte Stream trong Java Byte Stream trong Java được sử dụng để thực hiện input và output của các byte (8 bit).
Mặc dù có nhiều lớp liên quan tới byte stream nhưng các lớp thường được sử dụng nhất là: FileInputStream và FileOutputStream. Sau đây là một ví dụ sử dụng hai lớp này để sao chép một input file vào trong một output file: import java.*; public class CopyFile { public static void main(String args[]) throws IOException { FileInputStream in = null; FileOutputStream out = null; try { in = new FileInputStream("input.txt"); out = new FileOutputStream("output.txt"); int c; while ((c = in.close(); } } } } Bây giờ giả sử chúng ta có một file là input.txt có nội dung sau: Day la vi du ve sao chep file. Trong bước tiếp theo, biên dịch chương trình trên và thực thi nó, sẽ cho kết quả là tạo một file là output.txt có cùng nội dung như chúng ta có trong input. Vì thế, bạn đặt code trên vào trong CopyFile.java file và làm như sau: $javac CopyFile.java $java CopyFile Character Stream trong Java Byte Stream trong Java được sử dụng để thực hiện input và output của các byte (8 bit), trong khi đó, Character Stream trong Java được sử dụng để thực hiện input và output cho Unicode 16 bit.
Mặc dù có nhiều lớp liên quan tới character stream nhưng các lớp thường dùng nhất là FileReader và FileWriter… Mặc dù trong nội tại, FileReader sử dụng FileInputStream và FileWriter sử dụng FileOutputStream, nhưng có một điểm khác biệt lớn ở đây là FileReader đọc hai byte cùng một thời điểm và FileWriter ghi 2 byte cùng một lúc. Chúng ta có thể viết lại ví dụ trên mà sử dụng hai lớp này để sao chép một input file (có các ký tự Unicode) vào trong một output file.*; public class CopyFile { public static void main(String args[]) throws IOException { FileReader in = null; FileWriter out = null; try { in = new FileReader("input.txt"); out = new FileWriter("output.txt"); int c; while ((c = in.close(); } } } } Giả sử chúng ta có input.txt có nội dung sau: Day la vi du ve sao chep file. Trong bước tiếp theo, biên dịch chương trình trên và thực thi nó, sẽ cho kết quả là tạo một file là output.txt có cùng nội dung như chúng ta có trong input. Vì thế, bạn đặt code trên vào trong CopyFile.java file và làm như sau: $javac CopyFile.java $java CopyFile Standard Stream trong Java Tất cả các Ngôn ngữ lập trình cung cấp sự hỗ trợ cho I/O chuẩn, tại đây chương trình của người sử dụng có thể nhận đầu vào từ một bàn phím và sau đó tạo kết quả trên màn hình máy tính.
Nếu bạn đã biết về các ngôn ngữ C/C++, thì bạn phải biết về 3 thiết bị chuẩn là STDIN, STDOUT, và STDERR. Theo cách tương tự, Java cung cấp 3 Standard Stream sau: Đầu vào chuẩn (Standard Input): Nó được sử dụng để truyền dữ liệu tới chương trình của người dùng và thường thì một bàn phím được sử dụng như là đầu vào chuẩn và được biểu diễn như System. Đầu ra chuẩn (Standard Output): Nó được sử dụng để hiển thị kết quả đầu ra từ chương trình của người dùng và thường thì một màn hình máy tính được sử dụng như là đầu ra chuẩn và được biểu diễn như là System. Lỗi chuẩn (Standard Error): Được sử dụng để hiển thị các lỗi trong chương trình của người dùng và thường thì một màn hình máy tính được sử dụng như là lỗi chuẩn và được biểu diễn như là System.
Sau đây là một chương trình đơn giản tạo InputStreamReader để đọc luồng đầu vào chuẩn tới khi người sử dụng gõ một "q".*; public class ReadConsole { public static void main(String args[]) throws IOException { InputStreamReader cin = null; try { cin = new InputStreamReader(System.println("Nhap cac ky tu, 'q' de thoat."); char c; do { c = (char) cin.close(); } } } } Giữ code trên trong ReadConsole.java file và thực thi và biên dịch nó như dưới đây. Chương trình này tiếp tục đọc và hiển thị kết quả tới khi chúng ta nhấn phím "q".java $java ReadConsole Nhap cac ky tu, 'q' de thoat. 1 1 e e q q Đọc và Ghi File trong Java Như đã miêu tả trước đó, một Stream có thể được định nghĩa như là một dãy liên tục của dữ liệu. InputStream được sử dụng để đọc dữ liệu từ một nguồn vàOutputStream được sử dụng để ghi dữ liệu tới một đích.
Dưới đây là một cấu trúc có thứ tự của các lớp để xử lý các luồng Input và Output. Ghi dạng byte: File, FileInputStream, FileOutputStream File Lớp File trong Java biểu diễn các pathname của các file và thư mục theo phương thức trừu tượng. Lớp này được sử dụng để tạo các file và thư mục, để tìm kiếm các file, xóa các file, … Đối tượng File biểu diễn file/thư mục thực sự trên đĩa. Có các constructor sau để tạo một đối tượng File trong Java: Cú pháp sau tạo một đối tượng File mới từ một pathname trừu tượng cha và một chuỗi pathname con.
File(File parent, String child); Cú pháp sau tạo một đối tượng File mới bởi việc biến đổi chuỗi pathname đã cho thành một pathname trừu tượng. File(String pathname) Cú pháp sau tạo một đối tượng File mới từ một chuỗi pathname cha và một chuỗi pathname con. File(String parent, String child) Cú pháp sau tạo một đối tượng File mới bởi việc biến đổi URI đã cho thành một pathname trừu tượng. File(URI uri) Khi bạn có đối tượng File, thì có các phương thức sau giúp bạn thao tác các file trong Java: STT Phương thức và Miêu tả 1 public String getName() Trả về tên của file hoặc thư mục đã được biểu thị bởi pathname trừu tượng này 2 public String getParent() Trả về chuỗi pathname của pathname trừu tượng cha, hoặc null nếu pathname này không là tên của một thư mục cha 3 public File getParentFile() Trả về pathname trừu tượng của pathname trừu tượng cha, hoặc null nếu pathname này không là tên của một thư mục cha 4 public String getPath() Biến đổi pathname trừu tượng này thành một chuỗi pathname 5 public boolean isAbsolute() Kiểm tra có hay không pathname trừu tượng này là absolute.
Trả về true nếu là absolute, nếu không là false 6 public String getAbsolutePath() Trả về chuỗi pathname tuyệt đối của pathname trừu tượng này 7 public boolean canRead() Kiểm tra có hay không ứng dụng có thể đọc file, được biểu thị bởi pathname trừu tượng này. Trả về true nếu và chỉ nếu file đã xác định bởi pathname trừu tượng này là tồn tại và có thể được đọc từ ứng dụng; nếu không là false 8 public boolean canWrite() Kiểm tra có hay không ứng dụng có thể sửa đổi file, được biểu thị bởi pathname trừu tượng này. Trả về true nếu và chỉ nếu hệ thống file thực sự chứa một file được biểu thị bằng pathname trừu tượng này và ứng dụng được phép write tới file đó; nếu không là false 9 public boolean exists() Kiểm tra có hay không file hoặc thư mục được biểu thị bởi pathname trừu tượng này là tồn tại. Trả về true nếu và chỉ nếu file hoặc thư mục được biểu thị bởi pathname trừu tượng này là tồn tại; nếu không là false 10 public boolean isDirectory() Kiểm tra có hay không file được biểu thị bởi pathname trừu tượng này là một thư mục.
Trả về true nếu và chỉ nếu file được biểu thị bởi pathname trừu tượng này là tồn tại và là một thư mục; nếu không là false 11 public boolean isFile() Kiểm tra có hay không file được biểu thị bởi pathname trừu tượng này là một normal file. Một file là normal nếu nó không là một thư mục và ngoài ra, thỏa mãn các tiêu chuẩn khác phụ thuộc vào hệ thống. Bất kỳ một non-directory file được tạo bởi một ứng dụng Java được bảo đảm là một normal file. Trả về true nếu và chỉ nếu file được biểu thị bởi pathname trừu tượng này là một normal file; nếu không là false.
12 public long lastModified() Trả về time mà file được biểu thị bởi pathname trừu tượng này được sửa đổi lần cuối cùng. Trả về giá trị long biểu diễn thời gian mà file được sửa đổi lần cuối cùng, được tính toán bằng mili giây từ 00:00:00 GMT, 1/1/1970, hoặc 0L nếu file không tồn tại hoặc nếu một I/O error xuất hiện 13 public long length() Trả về độ dài của file được biểu thị bởi pathname trừu tượng này. Giá trị trả về là không rõ ràng nếu pathname này biểu thị một thư mục 14 public boolean createNewFile() throws IOException Tạo một file mới, trống với tên pathname trừu tượng này nếu và chỉ nếu một file với tên này chưa tồn tại. Trả về true nếu và chỉ nếu file với tên này không tồn tại và được tạo thành công; nếu file với tên này đã tồn tại, thì trả về false 15 public boolean delete() Xóa file hoặc thư mục được biểu thị bởi pathname trừu tượng này.
Nếu pathname này biểu thị một thư mục, thì thư mục phải là trống để bị xóa. Trả về true nếu và chỉ nếu file hoặc thư mục bị xóa thành công; nếu không là false 16 public void deleteOnExit() Yêu cầu rằng file hoặc thư mục được biểu thị bởi pathname trừu tượng này để bị xóa khi thiết bị ảo kết thúc 17 public String[] list() Trả về một mảng các chuỗi chỉ các file và thư mục trong thư mục được biểu thị bởi pathname trừu tượng này 18 public String[] list(FilenameFilter filter) Trả về một mảng các chuỗi chỉ các file và thư mục trong thư mục được biểu thị bởi pathname trừu tượng này mà thỏa mãn filter đã cho 20 public File[] listFiles() Trả về một mảng các pathname trừu tượng biểu thị các file trong thư mục được biểu thị bởi pathname trừu tượng này 21 public File[] listFiles(FileFilter filter) Trả về một mảng các pathname trừu tượng biểu thị các file và thư mục trong thư mục được biểu thị bởi pathname trừu tượng này mà thỏa mãn filter đã cho 22 public boolean mkdir() Tạo thư mục được chỉ bởi pathname trừu tượng này.