Bài giảng Lập trình Java cơ bản - Chương 9: Nhập xuất file, lặp và ngoài lệ
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình Java cơ bản - Chương 9: Nhập xuất file, lặp và ngoài lệ", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_lap_trinh_java_co_ban_chuong_9_nhap_xuat_file_lap.ppt
Nội dung text: Bài giảng Lập trình Java cơ bản - Chương 9: Nhập xuất file, lặp và ngoài lệ
- LẬPLẬP TRÌNHTRÌNH JAVAJAVA CƠCƠ BẢNBẢN Chương 9 NHẬP XUẤT FILE, LẶP VÀ NGOẠI LỆ Lê Tân Bộ môn: Lập trình máy tính 1
- Nội dung chương 9 n Nhập xuất file n Lặp n Toán tử điều kiện và lệnh nhảy n Kỹ thuật quản lý ngoại lệ 2
- 9.1 Nhập xuất file n Việc lưu trữ dữ liệu trong các biến, các mảng có tính chất tạm thời n Dữ liệu sẽ mất khi biến ra khỏi tầm ảnh hưởng của nó hoặc khi chương trình kết thúc. n File giúp chương trình có thể lưu trữ một lượng lớn dữ liệu, cũng như có thể lưu trữ dữ liệu trong một thời gian dài ngay cả khi chương trình kết thúc. 3
- 9.1 Nhập xuất file n Khai báo: Để nhập xuất sử dụng file, cần các khai báo sau • Nạp gói java.io.* • Chọn các tên và kiểu phù hợp cho các biến file và khai báo chúng. • Tạo một đối tượng file cho mỗi biến file. • Sử dụng các tên file trong các lệnh nhập-xuất • Đóng các file khi đã xong việc. • Tiến trình khởi tạo file sẽ kết hợp tên file với tên vật lý của file; chèn một con trỏ file đến điểm bắt đầu của file, trỏ vào ký tự đầu tiên; nếu file không tồn tại trên đĩa, một file rỗng được tạo ra; nếu file đã tồn tại trên đĩa, nó sẽ bị xoá đi. 4
- 9.1 Nhập xuất file n Khái niệm luồng: Tất cả những hoạt động nhập/xuất dữ liệu đều được quy về một khái niệm gọi là luồng (stream). n Luồng là nơi có thể “sản xuất” và “tiêu thụ” thông tin. n 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ý. n Tất cả các luồng đều có chung một nguyên tắc hoạt động. n Cùng một lớp, phương thức nhập xuất có thể dùng chung cho các thiết bị vật lý khác nhau. n Java định nghĩa hai kiểu luồng: luồng byte và luồng ký tự n Luồng 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. 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). 5
- 9.1 Nhập xuất file n Luồng byte (Byte Streams): Các luồng byte được định nghĩa dùng hai lớp phân cấp. n Mức trên cùng là hai lớp trừu tượng InputStream và OutputStream. n InputStream định nghĩa những đặc điểm chung cho những luồng nhập byte. n OutputStream mô tả cách xử lý của các luồng xuất byte. n Các lớp 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. 6
- 9.1 Nhập xuất file 7
- 9.1 Nhập xuất file 8
- 9.1 Nhập xuất file n Luồng ký tự (Character Streams): Các luồng ký tự được định nghĩa dùng hai lớp phân cấp. n Mức trên cùng là hai lớp trừu tượng Reader và Writer. n Lớp Reader dùng cho việc nhập dữ liệu của luồng n Lớp Writer dùng cho việc xuất dữ liệu cua luồng. n Những lớp dẫn xuất từ Reader và Writer thao tác trên các luồng ký tự Unicode. 9
- 9.1 Nhập xuất file 10
- 9.1 Nhập xuất file 11
- 9.1 Nhập xuất file n Luồng được định nghĩa trước (The Predefined Streams): Gói java.lang có định nghĩa lớp System, 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 trường được khai báo static trong lớp System. n System.out: luồng xuất chuẩn, mặc định là màn hình console. System.out là một đối tượng kiểu PrintStream. n 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. n System.err: luồng lỗi chuẩn, mặc định cũng là màn hình console. System.err cũng là một đối tượng kiểu PrintStream giống System.out. 12
- 9.1 Nhập xuất file n Sử dụng luồng Byte: InputStream và OutputStream là hai siêu lớp của tất cả những lớp luồng xuất nhập kiểu byte. n Những phương thức trong hai siêu lớp này tạo ra các ngoại lệ kiểu IOException. n Chúng có thể được dùng trong các lớp con. 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. 13
- 9.1 Nhập xuất file 14
- 9.1 Nhập xuất file 15
- 9.1 Nhập xuất file n Đọc dữ liệu từ màn hình Console import java.io.*; class ReadBytes { public static void main(String args[]) throws IOException { byte data[] = new byte[100]; System.out.print("Enter some characters."); System.in.read(data); System.out.print("You entered: "); for(int i=0; i < data.length; i++) System.out.print((char) data[i]); } } 16
- 9.1 Nhập xuất file n Đọc và ghi file dùng luồng Byte • Phương thức readLine() của lớp BuffereReader không sử dụng đối số, trả về một chuỗi. • Nó đọc một dòng vào từ file, bao gồm cả dấu hiệu kết thúc dòng (end-of-line mark), nhưng loại bỏ dấu hiệu EOL, rồi lưu phần còn lại của dòng tại vị trí trả về của chuỗi. Ví dụ: String line ; line = inFile.readLine( ) ; • Có thể sử dụng để nhập một giá trị số từ file, ví dụ: int numberOfDependents; line = inFile.readLine( ); numberOfDependents = Integer.valueOf(line).intValue( ); double taxRate ; line = inFile.readLine( ); taxRate = Double.valueOf( line ).doubleValue( ); 17
- 9.1 Nhập xuất file n Ví dụ sử dụng files: import java.io.*; // Các lớp file nằm ở đây public class EditLine { private static BufferedReader inFile; // file nhập dữ liệu private static PrintWriter outFile; // file xuất dữ liệu public static void main( String[ ] args ) throws IOException{ // Chuẩn bị các file để đọc và ghi dữ liệu inFile = new BufferedReader(new FileReader(“infile.dat”)); outFile = new PrintWriter( new FileWriter(“outfile.dat”)); . . . inFile.close( ); outFile.close( ); } } 18
- 9.1 Nhập xuất file n Phương thức write() của lớp FileWtite có thể nhận một giá trị kiểu int hoặc một đối tượng thuộc lớp String làm đối số. n Một đối số kiểu int trước hết phải được chuyển thành ký tự, sử dụng mã Unicode, sau đó được viết vào file như một ký tự. Ví dụ: FileWriter outFile ; outFile = new FileWriter(“outfile.dat”); outFile.write(‘Q’) ; outFile.write(“This is written to file.”); n Phương thức print() của lớp PrintWrite sử dụng một đối số thuộc kiểu dữ liệu nguyên thủy bất kỳ của Java, như char, int, long, float, double hoặc String. n Phương thức println() tự động thêm dấu hiệu kết thúc dòng (EOL) vào cuối những gì nó ghi lên file. Ví dụ: PrintWriter outFile ; outFile = new PrintWriter( new FileWriter(“outfile.dat”) ); outFile.println( “Average blood pressure is ” + avgBP + “ for “ + count + “ patients.” ); 19
- 9.2 Lặp n Lệnh lặp while: while (BT_L) { // thân_vòng_lặp; Lệnh; } 20
- 9.2 Lặp n Ví dụ: int i = 0; while (i < 100) { System.out.println("Welcome to Java!"); i++; } n Lưu ý: Không sử dụng giá trị dấu chấm động để kiểm tra đẳng thức trong điều khiển lặp (vì giá trị dấu chấm động là gần đúng) // data should be zero double data = Math.pow(Math.sqrt(2), 2) - 2; if (data = = 0) System.out.println("data is zero"); else System.out.println("data is not zero"); 21
- 9.2 Lặp n Lệnh lặp do-while: do { // thân_vòng_lặp; Lệnh; } while (BT_L); 22
- 9.2 Lặp n Hoạt động: BT_L là biểu thức logic. Máy thực hiện các lệnh trong thân vòng lặp (Lệnh) rồi kiểm tra BT_L. Nếu BT_L nhận giá trị true (đúng) thì lặp lại việc thực hiện (Lệnh) và cứ tiếp tục như vậy. Ngược lại, nếu BT_L nhận giá trị false (sai) thì kết thúc vòng lặp. n Ví dụ: int i = 0; do { System.out.println("Welcome to Java!"); i++; } while (i < 100) 23
- 9.2 Lặp n Lệnh lặp for: for (khởi_tạo; BT_L; công_việc) { // thân vòng lặp; Lệnh; } 24
- 9.2 Lặp n Hoạt động: BT_L là một biểu thức logic. Máy thực hiện lệnh khởi_tạo (thường là khởi tạo biến đếm), rồi kiểm tra BT_L. Nếu BT_L nhận giá trị true (đúng) thì thực hiện các lệnh trong thân vòng lặp (Lệnh), sau đó thực hiện công việc sau mỗi lần lặp (thường là cập nhật biến đếm), rồi quay lại bước kiểm tra, và cứ tiếp tục như vậy. Ngược lại, nếu BT_L nhận giá trị false (sai) thì kết thúc vòng lặp. n Ví dụ: int i; for (i = 0; i < 100; i++) { System.out.println("Welcome to Java! ” + i); } 25
- 9.2 Lặp n Lưu ý: Các trường hợp sau đây là đúng (về mặt cú pháp) for (int i = 1; i < 100; System.out.println(i++)); for (int i = 0, j = 0; (i + j < 10); i++, j++) { // Do something } 26
- 9.3 Toán tử điều kiện và lệnh nhảy n Toán tử điều kiện • Cú pháp: (BT_logic) ? bt1 : bt2 ; • Ý nghĩa: Nếu BT_logic nhận giá trị true (đúng) thì thực hiện bt1, ngược lại, thực hiện bt2. • Ví dụ: if (x > 0) y = 1 else y = -1; tương đương với: y = (x > 0) ? 1 : -1; 27
- 9.3 Toán tử điều kiện và lệnh nhảy n Lệnh break: Dùng lệnh break để thoát khỏi cấu trúc switch trong cùng chứa nó. n Tương tự, trong cấu trúc lặp, lệnh break dùng để thoát khỏi cấu trúc lặp trong cùng chứa nó. 28
- 9.3 Toán tử điều kiện và lệnh nhảy n Lệnh continue: Dùng để tiếp tục vòng lặp trong cùng chứa nó (ngược với break) 29
- 9.3 Toán tử điều kiện và lệnh nhảy n Nhãn (label): Không giống như C/C++, Java không hỗ trợ lệnh goto để nhảy đến một vị trí nào đó của chương trình. Java dùng kết hợp nhãn (label) với từ khóa break và continue để thay thế cho lệnh goto. Ví dụ: label: for ( ){ for ( ){ if ( ) break label; else continue label; } } 30
- 9.3 Toán tử điều kiện và lệnh nhảy n Định giá ngắn mạch: • Java sử dụng định giá ngắn mạch đối với các biểu thức logic có chứa các toán tử && và ||. • Các biểu thức logic với các toán tử && và || được định giá từ trái sang phải và việc định giá sẽ dừng lại ngay khi giá trị boolean đúng của toàn bộ biểu thức được tìm thấy. • Việc định giá biểu thức logic chỉ chứa && sẽ dừng lại và trả về giá trị false ngay khi xuất hiện giá trị false đầu tiên. • Việc định giá biểu thức logic chỉ chứa || sẽ dừng lại và trả về giá trị true ngay khi xuất hiện giá trị true đầu tiên. • Các biểu thức chứa & và | hoạt động tương tự như các biểu thức chứa && và ||, trừ một điều là chúng không có định giá ngắn mạch. 31
- 9.4 Kỹ thuật quản lý ngoại lệ n Ngoại lệ: Trong quá trình thực hiện chương trình thường xảy ra một số sự kiện đặc biệt hoặc các lỗi như sự tràn số, truy xuất đến chỉ số mảng nằm ngoài tập chỉ số, thực hiện lệnh đọc một phần tử cuối tập tin n Các sự kiện đó được gọi là ngoại lệ (exception). n Java nhận biết hai dạng của ngoại lệ, đó là dạng kiểm tra được và dạng không kiểm tra được. n Ngoại lệ không kiểm tra được có thể bỏ qua, nhưng chương trình phải nhận dạng một cách rõ ràng các ngoại lệ kiểm tra được. 32
- 9.4 Kỹ thuật quản lý ngoại lệ n Chuyển tiếp ngoại lệ: • Một ngoại lệ có thể được chuyển tiếp bằng cách thêm mệnh đề throws vào phần heading của phương thức. Mệnh đề này sẽ chỉ ra tên của ngoại lệ được chuyển tiếp. Ví dụ: • Bằng cách này, ngoại lệ được chuyển đến phương thức gọi, cho đến khi một bộ quản lý ngoại lệ được tìm thấy, hoặc chuyển kết thúc với JVM. 33
- 9.4 Kỹ thuật quản lý ngoại lệ n Ngoại lệ vào-ra (IOException): • Các lớp FileReader, BufferedReader, và FileWriter đều có thể phát ra một ngoại lệ gọi là IOException. • Phương thức PrintWriter không thể phát ra bất cứ ngoại lệ nào, nhưng phương thức tạo PrintWriter cần được chuyển một đối tượng FileWriter mà nó có thể phát sinh ngoại lệ vào -ra. n Ba công đoạn của quá trình quản lý ngoại lệ: • Định nghĩa ngoại lệ: thông qua việc mở rộng kiểu ngoại lệ, và việc được cung cấp một cặp các phương thức tạo gọi đến lớp cha. • Phát sinh ngoại lệ: qua việc sử dụng mệnh đề throw. • Quản lý ngoại lệ: qua việc sử dụng một mệnh đề throws để xác định kiểu của ngoại lệ được chuyển tiếp, hoặc qua việc sử dụng try-catch-finally để nắm bắt được ngoại lệ. 34
- 9.4 Kỹ thuật quản lý ngoại lệ n Ví dụ về chương trình tính thương 2 số thực • Định nghĩa một lớp ngoại lệ: //Định nghĩa một lớp ngoại lệ để xử lý lỗi thiết lập dữ liệu class DataSetException extends Exception { public DataSetException( ) { super( ); } public DataSetException( String message ) { super( message ); } } 35
- 9.4 Kỹ thuật quản lý ngoại lệ import java.io.*; public class SoNguyen{ static void processFile(BufferedReader inFile){ try{ // Nắm bắt ngoại lệ dataLine = inFile.readLine( ); double a = Double.valueOf(dataLine).doubleValue( ); dataLine = inFile.readLine( ); double b = Double.valueOf(dataLine).doubleValue( ); if (b == 0.0) throw new DataSetException(“Zero in “); else System.out.println(“”+(a/b)); } catch (IOException except){ System.out.println(“IOException with site ”); } catch (NumberFormatException except){ System.out.println(“NumberFormatException in site ”); }catch (DataSetException except){ System.out.println(except.getMessage( )); } } 36
- 9.4 Kỹ thuật quản lý ngoại lệ public static void main( String[ ] args ) throws FileNotFoundException, IOException { BufferedReader inFile; // file dữ liệu inFile = new BufferedReader(new FileReader(“inData.dat”)); String dataSetName; do { processFile(inFile); dataSetName = inFile.readLine( ); } while (dataSetName != null); inFile.close( ); } } 37
- Câu hỏi và bài tập 1. Nếu một chương trình cần nhập 1000 số nguyên, phương pháp nhập nào là thích hợp? 2. Câu lệnh nào sẽ đọc một dòng trong một file nhập infile và lưu số nguyên tương ứng vào biến number? 3. Hãy viết dòng đầu tiên của một lệnh while mà nó lặp lại cho đến khi giá trị của biến kiểu Boolean là done trở thành true. 4. Dạng lệnh lặp nào bạn sẽ sử dụng trong một chương trình để đọc giá đóng cửa của cổ phiếu đối với mỗi ngày trong tuần? 5. Năm bước trong việc sử dụng file nhập là gì? 6. Phương thức read đối với lớp FileReader sẽ trả về cái gì? 38
- Câu hỏi và bài tập 7. Hãy viết đoạn chương trình đếm số lần xuất hiện của số nguyên 28 trong một file chứa 100 số nguyên. 8. Viết đoạn chương trình xuất ra dãy giờ và phút trong một ngày, bắt đầu lúc 1:00 sáng và kết thúc lúc 12:59 sáng. 9. Thiết kế và viết một ứng dụng Java để nhập vào một số nguyên n lớn hơn 1 và tính tổng bình phương các số từ 1 đến n. Ví dụ, nếu nhập vào số 4, tổng sẽ là 30 (bằng 1 + 4 + 9 + 16). 10. Sử dụng vòng lặp for, viết một phương thức nhận hai biến int là x và n, và trả về giá trị xn. 11. Viết ứng dụng nhập vào hai chữ cái là tên viết tắt của một trong 64 tỉnh (thành) trong cả nước và hiển thị tên đầy đủ của tỉnh (thành) tương ứng. Nếu tên viết tắt là không hợp lệ, hãy hiển thị một thông báo lỗi và yêu cầu nhập tên viết tắt khác. Tên đầy đủ và viết tắt của 64 tỉnh (thành phố) do người lập trình tự quy định. Chương trình có hai nút bấm để nhập dữ liệu và kết thúc thực hiện 39