Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 40 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
40
Dung lượng
1,88 MB
Nội dung
Ngơn Ngữ Lập Trình C# public static void Main() { Image theImage = new Image(); // khơng có GUI để thực chọn lần // lượt hành động thực ImageProcessor theProc = new ImageProcessor(theImage); theProc.AddToEffects(theProc.BlurEffect); theProc.AddToEffects(theProc.FilterEffect); theProc.AddToEffects(theProc.RotateEffect); theProc.AddToEffects(theProc.SharpenEffect); theProc.ProcessImage(); } } } Kết quả: An image created Blurring image Filtering image Rotate image Sharpening image Trong ví dụ trên, đối tượng ImageProcessor tạo hiệu ứng thêm vào Nếu người dùng chọn làm mờ trước lọc ảnh, đơn giản đưa vào mảng ủy quyền theo thứ tự tương ứng Tương tự vậy, hành động lựa chọn người dùng mong muốn, ta đưa thêm nhiều ủy quyền vào tập hợp Chúng ta tưởng tượng việc hiển thị thứ tự hành động danh sách listbox cho phép người sử dụng xếp lại phương thức, di chuyển chúng lên xuống danh sách Khi hành động xếp lại cần thay đổi thứ tự tập hợp Ngoài ta đưa hoạt động vào sở liệu sau đọc chúng lúc thực Ủ y quyền dễ dàng cung cấp động cho ta phương thức gọi theo thứ tự xác định Multicasting Cơ chế multicasting cho phép gọi hai phương thức thực thi thông qua ủy quyền đơn Điều trở nên quan trọng xử lý kiện, thảo luận phần cuối chương 321 Cơ Chế Ủy Quyền - Sự Kiện Ngôn Ngữ Lập Trình C# Mục đích có ủy quyền gọi thực nhiều phương thức Điều hồn tồn khác với việc có tập hợp ủy quyền, số chúng gọi phương thức Trong ví dụ trước, tập hợp sử dụng để lưu giữ ủy quyền khác Tập hợp thêm ủy quyền nhiều lần, sử dụng tập hợp để xếp lại ủy quyền điều khiển thứ tự hành động gọi Với Multicasting tạo ủy quyền đơn cho phép gọi nhiều phương thức đóng Ví dụ, nút lệnh nhấn muốn thực nhiều hàh động Để làm điều đưa cho button tập hợp ủy quyền, để sáng rõ dễ dàng tạo ủy quyền Multicast Bất ủy quyền trả giá trị void ủy quyền multicast, ta đối xử với ủy quyền bình thường khơng Hai ủy quyền Multicast kết hợp với phép toán cộng (+) Kết ủy quyền Multicast gọi đến tất phương thức thực thi nguyên thủy hai bên Ví dụ, giả sử Writer Logger ủy quyền trả giá trị void, dòng lệnh theo sau kết hợp chúng lại với tạo ủy quyền Multicast mới: myMulticastDelegate = Writer + Logger; Chúng ta thêm ủy quyền vào ủy quyền Multicast toán tử cộng (+=) Phép toán thêm ủy quyền phía bên phải tốn tử vào ủy quyền Multicast bên trái Ví dụ minh họa sau, giả sử có Transmitter myMulticastDelegate ủy quyền, lệnh sau thực việc thêm ủy quyền Transmitter vào myMulticastDelegate: myMulticastDelegate += Transmitter; Để hiểu rõ ủy quyền Multicast tạo sử dụng, bước tìm hiểu thơng qua ví dụ 11.3 bên dưới, ví dụ minh họa tạo lớp có tên gọi MyClassWithDelegate lớp định nghĩa delegate, delegate lấy tham số chuỗi khơng có giá trị trả về: void delegate void StringDelegate( string s); Sau định lớp gọi MyImplementingClass lớp có ba phương thức, tất phương thức trả giá trị void nhận chuỗi làm tham số: WriteString, LogString, Transmitting Phương thức viết chuỗi xuất hình tiêu chuẩn, chuỗi thứ hai mơ viết vào log file, phương thức thứ ba mô việc chuyển chuỗi qua Internet Chúng ta tạo thể delegate để gọi phương thức tương ứng: Writer(“String passed to Writer\n”); Logger(“String passed to Logger\n”); Transmitter(“String passed to Transmitter\n”); Để xem cách kết hợp delegate, tạo thể delegate khác: MyClassWithDelegate.StringDelegate myMulticastDelegate; 322 Cơ Chế Ủy Quyền - Sự Kiện Ngôn Ngữ Lập Trình C# gán cho delegate kết phép cộng hai delegate cho trước: myMulticastDelegate = Writer + Logger; Tiếp theo thêm vào delegate delegate cách sử dụng toán tử (+=): myMulticastDelegate += Transmitter; Cuối cùng, thực việc xóa deleagate sử dụng tốn tử (-=): DelegateCollector -= Logger; Sau tồn ví dụ minh họa Ví dụ 11.3: Kết hợp delegate namespace Programming_CSharp { using System; public class MyClassWithDelegate { // khai báo delegate public delegate void StringDelegate(string s); } public class MyImplementingClass { public static void WriteString( string s) { Console.WriteLine(“Writing string {0}”, s); } public static void LogString( string s) { Console.WriteLine(“Logging string {0}”, s); } public static void TransmitString( string s) { Console.WriteLine(“Transmitting string {0}”, s); } } public class Test { public static void Main() { // định nghĩa StringDelegate MyClassWithDelegate.StringDelegate Writer, Logger, Transmitter; 323 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# // định nghĩa StringDelegate khác thực Multicasting MyClassWithDelegate.StringDelegate myMulticastDelegate; // tạo thể delegate truyền vào phương thức thực thi Writer = new MyClassWithDelegate.StringDelegate( MyImplementingClass.WriteString); Logger = new MyClassWithDelegate.StringDelegate( MyImplementingClass.LogString); Transmitter = new MyClassWithDelegate.StringDelegate( MyImplementingClass.TransmitString); // gọi phương thức delegate Writer Writer(“String passed to Writer\n”); // gọi phương thức delegate Logger Logger(“String passed to Logger\n”); //gọi phương thức delegate Transmitter Transmitter(“String passed to Transmitter\n”); // thông báo người dùng kết hợp hai delegate vào // multicast delegate Console.WriteLine(“myMulticastDelegate = Writer + Logger”); // kết hợp hai delegate myMulticastDelegate = Writer + Logger; // gọi phương thức delegate, hai phương thức thực myMulticastDelegate(“First string passed to Collector”); // bảo với người sử dụng thêm delegate thứ vào // Multicast delegate Console.WriteLine(“\nmyMulticastDeleagte += Transmitter”); // thêm delegate thứ ba vào myMulticastDelegate += Transmitter; // gọi thực thi Multicast delegate, lúc ba // phương thức gọi thực myMulticastDelegate(“Second string passed to Collector”); // bảo với người sử dụng xóa delegate Logger Console.WriteLine(“\nmyMulticastDelegate -= Logger”); // xóa delegate Logger myMulticastDelegate -= Logger; // gọi lại delegate, lúc thực hai phương thức myMulticastDelegate(“Third string passed to Collector”); }// end Main }// end class 324 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# }// end namespace Kết quả: Writing string String passed to Writer Logging string String passed to Logger Transmitting string String passed to Transmitter myMulticastDelegate = Writer + Logger Writing string First string passed to Collector Logging string First string passed to Collector myMulticastDelegate += Transmitter Writing string Second string passed to Collector Logging string Second string passed to Collector Transmitting string Second string passed to Collector myMulticastDelegate -= Logger Writing string Third string passed to Collector Transmitting string Third string passed to Collector Trong ví dụ trên, thể delegate định nghĩa ba delegate Writer, Logger, Transmitter gọi Delegate thứ tư myMulticastDelegate gán cách kết hợp hai delegate đầu, gọi, dẫn đến hai delegate gọi Khi delegate thứ ba thêm vào, kết myMulticastDelegate gọi tất ba phương thức delegate thực Cuối cùng, Logger xóa khỏi delegate, myMulticastDelegate gọi có hai phương thức thực thi Multicast delegate thể tốt việc ứng dụng xử lý kiện Khi kiện ví dụ nút lệnh nhấn, multicast delegate tương ứng gọi đến loạt phương thức xử lý kiện để đáp ứng lại với kiện Sự kiện Trong môi trường giao diện đồ họa (Graphical User Interfaces: GUIs), Windows hay trình duyệt web địi hỏi chương trình phải đáp ứng kiện Một kiện nút lệnh nhấn, mục menu chọn, hành động chép tập tin hồn thành, Hay nói ngắn gọn hành động xảy ra, ta phải đáp ứng lại kiện Chúng ta khơng thể đốn trước kiện xuất Hệ thống chờ nhận kiện, chuyển vào cho trình xử lý kiện thực Trong môi trường giao diện đồ họa, thành phần đưa kiện Ví dụ, kích vào nút lệnh, đưa kiện Click Khi thêm mục vào danh sách, đưa kiện ListChanged 325 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# Cơ chế publishing subscribing Trong ngôn ngữ C#, đối tượng publish tập hợp kiện lớp khác đăng ký Khi lớp publish đưa kiện, tất lớp đăng ký nhận cảnh báo Ghi chú: Tác giả Gamma (Addison Wesley, 1995) mô tả chế sau: “Định nghĩa đến nhiều phụ thuộc đối tượng đối tượng thay đổi trạng thái, tất đối tượng khác phụ thuộc vào cảnh báo cập nhật cách tự động” Với chế này, đối tượng nói “Ở có thứ mà tơi thơng báo cho bạn” lớp khác đăng ký đáp “Vâng, báo cho tơi biết chuyện xảy ra” Ví dụ, nút lệnh cảnh báo cho thành phần nhấn Nút lệnh gọi publisher phân phát kiện Click lớp khác lớp subscriber chúng đăng ký nhận kiện Click Sự kiện delegate Những kiện C# thực thi với delegate Lớp publisher định nghĩa delegate lớp subscriber phải thực thi Khi kiện xuất phương thức lớp subscriber gọi thông qua delegate Một phương thức dùng để xử lý kiện trình xử lý kiện (event handler) Chúng ta khai báo trình xử lý kiện làm với delegate khác Theo quy ước, trình xử lý kiện NET Framework trả giá trị void lấy hai tham số Tham số nguồn dẫn đến kiện, đối tượng publisher Và tham số thứ hai đối tượng dẫn xuất từ lớp EventArgs Yêu cầu phải thực trình xử lý kiện theo mẫu EventArgs lớp sở cho tất liệu kiện, lớp EventArgs thừa kế tất phương thức từ Object, thêm vào trường public static empty thể kiện khơng có trạng thái (cho phép sử dụng hiệu kiện không trạng thái) Lớp dẫn xuất từ EventArgs chứa thông tin kiện Sự kiện thuộc tính lớp phát kiện Từ khóa event điều khiển cách thuộc tính kiện truy cập lớp subscriber Từ khóa event thiết kế để trì cho cách thể publish/ subscribe Giả sử muốn tạo lớp Clock dùng kiện để cảnh báo lớp subscriber đồng hồ hệ thống thay đổi giá trị giây Gọi kiện OnSecondChange Chúng ta khai báo kiện kiểu delegate xử lý kiện sau: [attributes] [modifiers] event type member- name Ví dụ khai báo sau: 326 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# public event SecondChangeHandler OnSecondChange; Trong ví dụ ta khơng dùng thuộc tính, modifier abstract, new, override, static, virtual, bốn access modifier, trường hợp public Modifier theo sau từ khóa event Trường type trường hợp ví dụ delegate mà muốn liên hệ với kiện, SecondChangeHandler Tên thành viên tên kiện, trường hợp OnSecondChange Thông thường, tên kiện bắt đầu với từ On Tóm lại, khai báo OnSecondChange kiện thực thi delegate có kiểu SecondChangeHandler Ta có khai báo cho delegate sau: public delegate void SecondChangeHandler( object clock, TimeInfoEventArgs timeInformation); Như nói trước đây, theo quy ước trình xử lý kiện phải trả giá trị void phải lấy hai tham số: nguồn phát kiện (trong trường hợp clock) đối tượng dẫn xuất từ EventArgs, TimeInfoEventArgs Lớp TimeInfoEventArgs định nghĩa sau: public class TimeInfoEventArgs : EventArgs { public TimeInfoEventArgs(int hour, int minute, int second) { this.hour = hour; this.minute = minute; this.second = second; } public readonly int hour; public readonly int minute; public readonly int second; } Đối tượng TimeInfoEventArgs có thơng tin phút giây thời Nó định nghĩa khởi tạo, ba phương thức, biến nguyên readonly Ngoài việc thêm vào kiện delegate, lớp đối tượng Clock có ba biến thành viên : hour, minute, second Cuối phương thức Run(): public void Run() { for(;;) { // ngừng 10 giây Thread.Sleep( 10 ); 327 Cơ Chế Ủy Quyền - Sự Kiện Ngôn Ngữ Lập Trình C# // lấy thời gian hành System.DateTime dt = System.DateTime.Now; // giây thay đổi cảnh báo cho subscriber if ( dt.Second != second) { // tạo TimeInfoEventArgs để truyền // cho subscriber TimeInfoEventArgs timeInformation = new TimeInfoEventArgs( dt.Hour, dt.Minute, dt.Second); // có lớp đăng ký cảnh báo if ( OnSecondChange != null) { OnSecondChange( this, timeInformation); } } // cập nhật trạng thái this.second = dt.Second; this.minute = dt.Minute; this.hour = dt.Hour; } } Phương thức Run tạo vịng lặp vơ hạn để kiểm tra định kỳ thời gian hệ thống Nếu thời gian thay đổi từ đối tượng Clock hành, cảnh báo cho tất subscriber sau cập nhật lại trạng thái Bước ngừng 10 giây: Thread.Sleep(10); Ở sử dụng phương thức tĩnh lớp Thread từ System.Threading NET Sử dụng phương thức Sleep() để kéo dài khoảng cách hai lần thực vòng lặp Sau ngừng 10 mili giây, phương thức kiểm tra thời gian hành: System.DateTime dt = System.DateTime.Now; Cứ khoảng 100 lần kiểm tra, giây gia tăng Phương thức ghi nhận thay đổi cảnh báo đến subscriber Để làm điều này, phải tạo đối tượng TimeInfoEventArgs: if ( dt.Second != second) { // tạo TimeInfoEventArgs để truyền cho subscriber TimeInfoEventArgs timeInformation = new TimeInfoEventArgs( dt.Hour, dt.Minute, dt.Second); 328 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# } Và để cảnh báo cho subscriber cách kích hoạt kiện OnSecondChange: // cảnh báo cho subscriber if ( OnSecondChange != null) { OnSecondChange( this, timeInformation); } Nếu kiện khơng có lớp subscriber đăng ký ước lượng giá trị null Phần kiểm tra bên xác định giá trị kiện có phải null hay khơng, để đảm bảo có tồn lớp đăng ký nhận kiện trước gọi kiện OnSecondChange Chúng ta lưu ý OnSecondChange lấy hai tham số: nguồn phát kiện đối tượng dẫn xuất từ lớp EventArgs Ở thấy tham chiếu this lớp clock truyền clock nguồn phát kiện Tham số thứ hai đối tượng TimeInfoEventArgs tạo dòng lệnh bên Một kiện phát gọi phương thức đăng ký với lớp Clock thông qua delegate, kiểm tra điều sau Một mà kiện phát ra, cập nhật lại trạng thái lớp Class: this.second = dt.Second; this.minute = dt.Minute; this.hour = dt.Hour; Sau xây dựng lớp đăng ký vào kiện Chúng ta tạo hai lớp Lớp lớp DisplayClock Chức lớp khơng phải lưu giữ thời gian mà để hiển thị thời gian hành hình console Để đơn giản tạo hai phương thức cho lớp Phương thức thứ có tên Subscribe, phương thức chịu trách nhiệm đăng ký kiện OnSecondChange lớp Clock Phương thức thứ hai tạo trình xứ lý kiện TimeHasChanged: public class DisplayClock { public void Subscrible(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(TimeHasChanged); } public void TimeHasChanged( object theClock, TimeInfoEventArgs ti) { Console.WriteLine(“Current Time: {0]:{1}:{2}”, ti.hour.ToString(), ti.minute.ToString(), ti.Second.ToString()); 329 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# } } Khi phương thức Subscribe gọi, tạo delegate SecondChangeHandler mới, truyền vào phương thức xử lý kiện TimeHasChanged Sau đăng ký delegate với kiện OnSecondChange Clock Lớp thứ hai mà tạo đáp ứng kiện này, tên LogCurrentTime Thông thường lớp ghi lại kiện vào tập tin, với mục đích minh họa chúng ta, ghi hình console: public class LogCurrentTime { public void Subscribe(Clock theClock) { theClock.OnSecondChange += new Clock.SecondChangeHandler(WriteLogEntry); } // thông thường phương thức viết file // minh họa xuất // hình console mà thơi public void WriteLogEntry( object theClock, TimeInfoEventArgs ti) { Console.WriteLine(“Logging to file: {0}:{1}:{2}”, ti.hour.ToString(), ti.minute.ToString(), ti.second.ToString()); } } Ghi kiện thêm vào cách sử dụng toán tử += Điều cho phép kiện thêm vào kiện OnSecondChange đối tượng Clock mà khơng có phá hủy kiện đăng ký Khi LogCurrentTime đăng ký kiện OnSecondChange, không muốn việc đăng ký làm đăng ký lớp DisplayClock trước Tất phần cịn lại cần thực tạo lớp Clock, tạo mộ đối tượng DisplayClock bảo đăng ký kiện Sau tạo đối tượng LogCurrentTime đăng ký kiện tương tự Cuối thực thi phương thức Run Clock Tất phần trình bày ví ụ 11.4 Ví dụ 11.4: làm việc với kiện namespace Programming_CSharp 330 Cơ Chế Ủy Quyền - Sự Kiện Ngôn Ngữ Lập Trình C# x x x x x x x x x x x x Vòng lặp thực thông qua biến lặp giá trị double, bước lặp tăng Giá trị Sin lấy thông qua việc sử dụng hàm Math.Sin Do giá trị Sin từ -1 đến dễ hiển thị hơn, giá trị chuyển từ -10 đến 10 Để chuyển thành giá trị ta nhân với 10 sau thực việc làm tròn cách dùng hàm Round Math Kết phép nhân làm tròn giá trị từ -10 đến 10 gán cho val2 Vòng lặp for thứ hai thực việc xuất ký tự hình Lớp thao tác tập tin Khả để viết thông tin vào tập tin hay đọc thơng tin từ tập tin làm cho chương trình có nhiều hiệu Hơn nữa, có nhiều lần muốn có khả làm việc với tập tin hữu Phần tiếp sau tìm hiểu đặc tính việc thao tác tập tin Điều theo sau khái niệm quan trọng tập tin luồng (stream) Sao chép tập tin Một lớp tập tin tồn bên lớp sở gọi File, lớp định vị bên namespace System.OI Lớp File chứa số phương thức tĩnh sử dụng để thao tác tập tin Thật vậy, tất phương thức bên lớp File điều tĩnh Bảng 12.2 liệt kê phương thức lớp File Lớp File Phương thức Mô tả AppendText Nối văn vào tập tin Tạo tập tin từ tập tin hữu Copy 346 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# Create Tạo tập tin vị trí xác định CreateText Tạo tập tin lưu giữ text Xóa tập tin vị trí xác định Tập tin phải hữu không phát sinh ngoại lệ Delete Exists GetAttributes GetCreationTime GetLastAccessTime GetLastWriteTime Move Open OpenRead OpenText OpenWrite SetAttributes SetCreationTime SetLastAccessTime SetLastWriteTime Kiểm tra xem tập tin có thực hữu vị trí Lấy thơng tin thuộc tính tập tin Thơng tin bao gồm: tập tin có bị nén hay khơng, tên thư mục, có thuộc tính ẩn, thuộc tính đọc, tập tin hệ thống Trả ngày tập tin tạo Trả ngày tập tin truy cập lần cuối Trả ngày tập tin viết lần cuối Cho phép tập tin di chuyển vào vị trí đổi tên tập tin Mở tập tin vị trí đưa Bằng việc mở tập tin viết thơng tin hay đọc thơng tin từ Mở tập tin hữu để đọc Mở tập tin để đọc dạng text Mở tập tin xác định để viết Thiết lập thuộc tính cho tập tin Thiết lập ngày tạo tập tin Thiết lập lại ngày mà tập tin truy cập lần cuối Thiết lập ngày mà tập tin cập nhật lần cuối Bảng 12.2 : Một số phương thức thao tác tập tin Chương trình 12.5 sau minh họa việc chép tập tin Ví dụ 12.5: Sao chép tập tin // file : filecopy.cs: chép tập tin // sử dụng tham số dòng lệnh namespace Programming_CSharp { using System; using System.IO; public class Tester { public static void Main() 347 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# { string[] CLA = Environment.GetCommandLineArgs(); if ( CLA.Length < 3) { Console.WriteLine(“Format: {0} orig-file new-file”, CLA[0]); } else { string origfile = CLA[1]; string newfile = CLA[2]; Console.Write(“Copy ”); try { File.Copy(origfile, newfile); } catch (System.IO.FileNotFoundException) { Console.WriteLine(“\n{0} does not exist!”, origfile); return; } catch (System.IO.IOException) { Console.WriteLine(“\n{0} already exist!”, newfile); return; } catch (Exception e) { Console.WriteLine(“\nAn exception was thrown trying to copy file”); Console.WriteLine(); return; } Console.WriteLine(“ Done”); } } } } 348 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# Chương trình thực cách sau biên dịch tập tin filecopy.exe ta gọi thực tập tin với tham số dòng lệnh sau: filecopy.exe filecopy.cs filecopy.bak Tập tin filecopy.cs hữu tập tin filecopy.bak chưa hữu lệnh thực thi Sao thực thi xong chương trình tập tin filecopy.bak tạo Nếu thực chương trình lần thứ hai với tham số vậy, nhận kết xuất sau: Copy filecopy.bak already exists! Nếu thực chương trình mà khơng có tham số nào, hay có tham số, nhận kết sau : Format d:\working\filecopy\filecopy.exe orig-file new-file Cuối cùng, điều tệ xảy thực chép tập tin nguồn không tồn tại: Copy filecopy.cs does not exist! Như ta thấy tất kết có chương trình minh họa 12.5 Chương trình thực việc chép tập tin kiểm tra tất tình có thực việc xử lý ngoại lệ Điều cho thấy chương trình vừa đáp ứng mặt logic lập trình vừa đáp ứng việc xử lý ngoại lệ Như biết lệnh sau: string[] CLA = Environment.GetCommandLineArgs(); thực việc lấy tham số dòng lệnh cấp cho chương trình Lớp Environment tìm hiểu sử dụng phần trước Lệnh sau kiểm tra xem chương trình có nhận hởn giá trị tham số dịng lệnh hay khơng if ( CLA.Length < 3) { Console.WriteLine(“Format: {0} orig-file new-file”, CLA[0]); } Nếu giá trị nhỏ 3, người sử dụng không cung cấp đủ thông tin Nên nhớ rằng, sử dụng phương thức GetCommandLineArgs, giá trị mà nhận tên chương trình Phần lại tham số dòng lệnh theo sau Điều có nghĩa cần thiết giá trị: tên chương trình, tên tập tin nguồn, tên tập tin Nếu nhập vào không đủ tham số dịng lệnh, chương trình xuất thơng báo với tên chương trình thực đọc GetCommandLineArgs Nếu cung cấp đầy đủ tham số, việc xử lý chép thực Để dễ theo dõi chương trình xuất thông báo việc chép file: 349 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# Console.Write(“Copy ”); Console.WriteLine(“ Done”); Mặc dùng việc chép tập tin khơng có phức tạp, lưu ý chương trình có thêm vào đoạn xử lý ngoại lệ Việc gọi hàm Copy File bao bọc khối try, sau ba thể Catch theo sau Bởi có nhiều thứ gây lỗi hoạt động tập tin, đề nghị nên đảm bảo cho chương trình thực việc bắt giữ xử lý ngoại lệ tương ứng Hầu hết phương thức File có ngoại lệ định nghĩa cho số lỗi quan trọng xuất Khi tra cứu tài liệu trực tuyến cho lớp Chúng ta tìm thấy ngoại lệ định nghĩa cho phương thức đưa Một cách thực hành lập trình tốt thêm vào đoạn xử lý ngoại lệ với ngoại lệ xuất Trong chương trình ngoại lệ xử lý cho việc gọi hàm Copy() là: catch (System.IO.FileNotFoundException) { Console.WriteLine(“\n{0} does not exist!”, origfile); return; } Ngoại lệ phát sinh tập tin mà cố chép khơng tìm thấy, ngoại lệ đặt tên FileNotFoundException Ngoại lệ bắt IOException Ngoại lệ phát sinh từ số ngoại lệ khác Bao gồm thư mục khơng tìm thấy (DirectoryNotFoundException), kết thúc tập tin khơng đựơc tìm thấy (EndOfStreamException), có lỗi đọc tập tin (FileLoadException), lỗi tập tin không tìm thấy, ngoại lệ bắt xử lý ngoại lệ bên Ngoại lệ phát sinh tập tin mà cần tạo tồn Cuối cùng, bắt giữ ngoại lệ khơng mong đợi cịn lại sử dụng ngoại lệ chung hay ngoại lệ tổng qt Bởi khơng biết ngun nhân việc xảy ngoại lệ, hiển thị thơng điệp thân ngoại lệ phát sinh Ghi chú: Nên sử dụng xử lý ngoại lệ thao tác tập tin Phong cách lập trình tốt khơng nên nghĩ người sử dụng cung cấp cho chương trình thứ mà chương trình cần sử dụng tham số dịng lệnh Lấy thơng tin tập tin Ngồi lớp File cung cấp từ thư viện sở, lớp khác thường xuyên sử dụng thể làm việc với tập tin lớp FileInfo Chương trình 12.6 minh họa việc sử dụng lớp Trong chương trình lấy tên tập tin hiển thị kích thước ngày quan trọng liên quan đến việc tạo, bổ sung tập tin Ví dụ 12.6: Sử dụng lớp FileInfo 350 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# // Filsize.cs namespace Programming_CSharp { using System; using System.IO; public class Tester { public static void Main() { string[] CLA = Environment.GetCommandLineArgs(); FileInfo fiExe = new FileInfo( CLA[0] ); if ( CLA.Length < 2) { Console.WriteLine(“Format: {0} filename”, fiExe.Name); } else { try { FileInfo fiFile = new FileInfo( CLA[1]); if (fiFile.Exists) { Console.WriteLine(“******************************”); Console.WriteLine(“{0} {1}”,fiFile.Name, fiFile.Length); Console.WriteLine(“******************************”); Console.WriteLine(“Last access: {0}”,fiFile.LastAccessTime); Console.WriteLine(“Last write: {0}”, fiFile.LastWriteTime); Console.WriteLine(“Creation: {0}”, fiFile.CreationTime); Console.WriteLine(“******************************”); } else { Console.WriteLine(“{0} doesn’t exist!”, fiFile.Name); } } catch (System.IO.FileNotFoundException) { 351 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# Console.WriteLine(“\n{0} does not exists!”, CLA[1]); return; } catch (Exception e) { Console.WriteLine(“\n An exception was thrown trying to copy file”); Console.WriteLine(); return; }// end catch }// end else }// end Main }// end class }// end namespace Kết quả: ****************************** filesize.cs 1360 ****************************** Last access: 12/5/2002 12:00:00 AM Last write: 12/5/2002 5:50:50 PM Creation: 12/5/2002 5:53:31 PM ****************************** Một đối tượng FileInfo tạo gắn với tập tin tương ứng: FileInfo fiInfo = new FileInfo( CLA[1]); Tham số khởi dựng lớp FileInfo xác định tên tập tin mà chứa nhận thơng tin, trường hợp lấy tham số thứ hai tham số dòng lệnh làm tập tin mà thực Nếu người dùng khơng nhập tên tập tin chương trình in tên chương trình Làm việc với tập tin liệu Phần trước thực công việc lấy thông tin tập tin chép tập tin sang tập tin Việc thực quan trọng tập tin đọc viết thông tin từ tập tin Trong phần tìm hiểu luồng nhập xuất cách tạo tập tin để ghi hay mở tập tin tồn để đọc thông tin Luồng nhập xuất Thuật ngữ tập tin nói chung liên quan đến thông tin lưu trữ bên ỗ đĩa nhớ Khi làm việc với tập tin, bao hàm với việc sử dụng luồng 352 Các Lớp Cơ Sở NET Ngôn Ngữ Lập Trình C# Nhiều người nhầm lẫn khác tập tin luồng Một luồng đơn giản luồng thông tin, chứa thông tin chuyển qua, cịn tập tin để lưu trữ thơng tin Một luồng sử dụng để gởi nhận thông tin từ nhớ, từ mạng, web, từ chuỗi, Một luồng sử dụng để vào với tập tin liệu Thứ tự việc đọc tập tin Khi đọc hay viết tập tin, cần thiết phải theo trình tự xác định Đầu tiên phải thực công việc mở tập tin Nếu tạo tập tin, việc mở tập tin lúc với việc tạo tập tin Khi tập tin mở, cần thiết phải tạo cho luồng để đặt thơng tin vào tập tin lấy thông tin từ tập tin Khi tạo luồng, cần thiết phải thông tin trực tiếp qua luồng Sau tạo luồng gắn với tập tin, lúc thực việc đọc ghi liệu tập tin Khi thực việc đọc thông tin từ tập tin, cần thiết phải kiểm tra xem trỏ tập tin tới cuối tập tin chưa, tức đọc đến cuối tập tin hay chưa Khi hồn thành việc đọc ghi thơng tin tập tin tập tin cần phải đóng lại Tóm lại bước để làm việc với tậo tin là: Bước 1: Mở hay tạo tập tin Bước 2: Thiết lập luồng ghi hay đọc từ tập tin Bước 3: Đọc hay ghi liệu lên tập tin Bước 4: Đóng lập tin lại Các phương thức cho việc tạo mở tập tin Có nhiều kiểu luồng khác Chúng ta sử dụng luồng khác phương thức khác phụ thuộc vào kiểu liệu bên tập tin Trong phần này, việc đọc/ghi thực tập tin văn Trong phần học cách đọc viết thông tin tập tin nhị phân Thông tin nhị phân bao hàm khả mạnh lưu trữ giá trị số kiểu liệu khác Để mở tập tin đĩa cho việc đọc viết tập tin văn bản, cần phải sử dụng hai lớp File FileInfo Một vài phương thức sử dụng lớp Các phương thức bao gồm: AppendText Create CreateText Open OpenRead OpenText OpenWrite Mở tập tin để tập tin thêm văn vào Tạo luồng StreamWriter sử dụng để thêm vào văn Tạo tập tin Tạo mở tập tin văn Tạo luồng StreamWriter Mở tập tin để đọc/viết Mở FileStream Mở tập tin để đọc Mở tập tin văn để đọc Tạo StreamReader để sử dụng Mở tập tin cho việc đọc ghi 353 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# Làm để biết sử dụng lớp File xác sử dụng lớp FileInfo chúng chứa phương thức tương tự với Thật hai lớp có nhiều khác biệt Lớp File chứa tất phương thức tĩnh, thêm vào lớp File tự động kiểm tra permission tập tin Trong muốn dùng lớp FileInfo phải tạo thể lớp Nếu muốn mở tập tin lần tốt sử dụng lớp File, tổ chức việc sử dụng tập tin nhiều lần bên chương trình, tốt ta dùng lớp FileInfo Hoặc không chắn cách sử dụng sử dụng lớp FileInfo Viết vào tập tin văn Cách tốt để nắm vững cách thức làm việc với tập tin bắt tay vào tìm hiểu chương trình Trong phần tìm hiểu ví dụ minh họa việc tạo tập tin văn sau viết lại thơng tin vào Ví dụ 12.7: Viết liệu vào tập tin văn //writing.cs:: viết vào tập tin văn namespace Programming_CSharp { using System; using System.IO; public class Tester { public static void Main(String[] args) { if (args.Length < 1) { Console.WriteLine(“Phai nhap ten tap tin.”); } else { StreamWriter myFile = File.CreateText( args[0]); myFile.WriteLine(“Khong co viec gi kho”); myFile.WriteLine(“Chi so long khong ben”); myFile.WriteLine(“Dao nui va lap bien”); myFile.WriteLine(“Quyet chi at lam nen”); for(int i=0; i < 10; i++) { 354 Các Lớp Cơ Sở NET Ngôn Ngữ Lập Trình C# myFile.Write(“{0} ”,i); } myFile.Close(); } } } } Khi chạy chương trình phải cung cấp tên tập tin tạo mới, không cung cấp chương trình khơng thực việc tạo tập tin Giả sử có cung cấp tham số dịng lệnh cho chương trình tập tin văn tạo có nội dung sau: Khong co viec gi kho Chi so long khong ben Dao nui va lap bien Quyet chi at lam nen Trong chương trình khơng thực việc xử lý ngoại lệ Điều dẫn đến chương trình phát sinh ngoại lệ ngoại lệ không xử lý Đây cách lập trình khơng tốt, nên u cầu người đọc nên thêm xử lý ngoại lệ vào chương trình trên, ngoại lệ tương tự ngoại lệ ví dụ trước Như thấy hàm Main có tham số tham số nhận thông qua dịng lệnh, ví dụ trước, chương trình nhận tham số dịng lệnh thơng qua lớp Environment, cịn ta khai báo tham số dòng lệnh trực tiếp cho chương trình Dịng lệnh hàm Main() kiểm tra số tham số nhập vào, khơng có tham số chương trình xuất thơng báo khơng có tên tập tin kết thúc chương trình Trong trường hợp cung cấp tham số đầy đủ chương trình thực việc tạo tập tin Phương thức CreateText lớp File gọi để tạo đối tượng StreamWriter gọi myFile Tham số truyền cho hàm tên tập tin tạo Kết cuối dòng lệnh tạo tập tin văn Dữ liệu s4 đưa vào tập tin thơng qua StreamWriter với thể myFile Ghi chú: Nếu tập tin hữu với tên tập tin mà tạo tập tin cũ viết chồng, tức liệu bên tập tin cũ bị xóa Hình sau minh họa việc thực tạo tập tin đưa liệu vào 355 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# Data to be written Disk file arg[0] myFile - StreamWriter Hình 12.3 : Mơ tả thực tạo tập tin đưa liệu vào Khi luồng thiết lập đến tập tin, viết vào luồng viết vào tập tin: myFile.WriteLine(“Khong co viec gi kho”); Dòng lệnh viết chuỗi vào tập tin, việc viết giống viết hình console Nhưng viết thiết bị khác, tức tập tin Sau thực tồn cơng việc, cần thiết phải đóng luồng lại cách gọi phương thức Close Đọc tập tin văn Đọc liệu từ tập tin văn tương tự việc viết thông tin vào Ví dụ minh họa tiếp sau thực việc đọc tập tin mà tạo từ chương trình minh họa 12.7 trước Đây chương trình đọc tập tin văn Ví dụ 12.8: Đọc tập tin văn using System; using System.IO; namespace Programming_CSharp { public class Tester { public static void Main(string[] args) { if ( args.Length < 1) { Console.WriteLine(“Phai nhap ten tap tin”); } else { 356 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# string buffer; StreamReader myFile = File.OpenText( args[0]); while ( (buffer = myFile.ReadLine()) !=null) { Console.WriteLine(buffer); } myFile.Close(); } } } } Nếu nhập tên tập tin vừa tạo ví dụ trước kết chương trình thực sau: Kết quả: Khong co viec gi kho Chi so long khong ben Dao nui va lap bien Quyet chi at lam nen Nếu chương trình cung cấp đầy đủ tên tập tin bắt đầu thực việc đọc thơng tin Đầu tiên khai báo chuỗi dùng làm chỗ lưu thông tin đọc tử tập tin Để mở tập tin văn phương thức OpenText gọi Phương thức truyền vào tên tập tin văn cần mở Một lần luồng tên myFile tạo gắn với tập tin cho, luồng có kiểu StreamReader Phương thức ReadLine() myFile thực việc đọc dòng tập tin sau xuất hình console Việc đọc kết hợp với việc kiểm tra đọc đến cuối tập tin chưa, đọc đến cuối tập tin, tức hàm ReadLine() trả chuỗi rỗng, lúc chương trình kết thúc việc đọc Cuối hàm Close gọi để đóng tập tin lại, chương trình chấm dứt Trong chương trình không xử lý ngoại lệ, tập tin không tồn chương trình phát sinh ngoại lệ ngoại lệ không xử lý Đề nghị người đọc nên đưa vào đoạn xử lý ngoại lệ tương tự ví dụ 12.6 Viết thơng tin nhị phân vào tập tin Nếu sử dụng tập tin văn bản, lưu liệu kiểu số phải thực việc chuyển đổi sang dạng chuỗi ký tự để lưu vào tập tin văn lấy 357 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# ta lấy giá trị chuỗi ký tự ta phải chuyển sang dạng số Đôi muốn có cách thức tốt để lưu trực tiếp giá trị vào tập tin sau đọc trực tiếp giá trị từ tập tin Ví dụ viết số lượng lớn số integer vào tập tin số nguyên, ta đọc giá trị số integer Trường hợp chúng viết vào tập tin với dạng văn bản, đọc ta phải đọc văn phải chuyển giá trị từ chuỗi đến số integer Tốt việc phải thực thêm bước chuyển đổi, ta gắn kiểu luồng nhị phân BinaryStream vào tập tin, sau đọc ghi thơng tin nhị phân từ luồng Tiếp theo ta xem ví dụ minh họa việc đọc viết liệu nhị phân vào tập tin Mặc dù chương trình thực việc viết 100 giá trị integer vào tập tin dễ dàng viết kiểu liệu khác Ghi chú: Thông tin nhị phân thông tin định dạng kiểu lưu trữ liệu Ví dụ 12.9: Viết vào tập tin nhị phân //binarywriter.cs using System; using System.IO; namespace Programming_CSharp { public class Tester { public static void Main(string[] args) { if ( args.Length < 1) { Console.WriteLine(“Phai nhap ten tap tin!”); } else { FileStream myFile = new FileStream( args[0], FileMode.CreateNew); BinaryWriter bwFile = new BinaryWriter(myFile); for (int i=0; i < 100; i++) { bwFile.Write(i); } bwFile.Close(); myFile.Close(); } 358 Các Lớp Cơ Sở NET Ngơn Ngữ Lập Trình C# } } } Cũng tương tự ví dụ tên tập tin đưa vào tham số dòng lệnh Nếu chương trình nhập tham số đầy đủ, chương trình thực việc viết thơng tin nhị phân vào tập tin, khơng có output hình console Nếu mở tập tin xem thấy ký tự mở rộng đựơc thể hiện, không thấy số đọc Trong chương trình chưa thực việc xử lý ngoại lệ Nếu thực việc viết thông tin vào tập tin hữu, ngoại lệ phát sinh thực lệnh: FileStream myFile = new FileStream( args[0], FileMode.CreateNew); Trong chương trình 12.9 thực việc tạo mở tập tin khác với việc mở tập tin văn Lệnh tạo đối tượng FileStream gọi myFile Luồng gắn với tập tin thông qua khởi dựng Tham số khởi dựng tên tập tin mà tạo (args[0]), tham số thứ hai mode mà mở Tham số giá trị kiểu liệt kê FileMode, chương trình thực việc tạo để ghi nên sử dụng giá trị FileMode.CreateNew Bảng 12.3 sau liệt kê mode giá trị khác kiểu liệt kê FileMode Giá trị Định nghĩa Append Mở tập tin hữu tạo tập tin Create Tạo tập tin Nếu tập tin hữu, bị xóa tập tin tạo với tên CreateNew Tạo tập tin Nếu tập tin tồn ngoại lệ phát sinh Open Mở tập tin hữu OpenOrCreate Mở tập tin hay tạo tập tin tập tin chưa tồn Truncate Mở tập tin hữu xóa nội dung Bảng 12.4: Giá trị FileMode Sau tạo FileStream, cần thiết phải thiết lập để làm việc với liệu nhị phân Dịng lệnh tiếp theo: BinaryWriter bwFile = new BinaryWriter(myFile); Dòng thiết lập kiểu viết liệu nhị phân vào luồng cách khai báo kiểu BinaryWrite Đối tượng thể BinaryWrite bwFile tạo myFile truyền vào khởi dựng BinaryWrite, gắn bwFile với myFile for (int i=0; i < 100; i++) { bwFile.Write(i); 359 Các Lớp Cơ Sở NET Ngôn Ngữ Lập Trình C# } Vịng lặp thực việc viết trực tiếp giá trị integer vào BinaryWrite bwFile cách sử dụng phương thức Write Dữ liệu viết kiểu liệu đặc biệt khác Trong chương trình sử dụng giá trị integer Khi thực xong công việc viết vào tập tin, cần thiết phải đóng luồng mà chúng tả mở Đọc thông tin nhị phân từ tập tin Trong phần trước thực việc viết thông tin nhị phân vào tập tin, mong muốn đọc thông tin ghi vào tập tin Việc đọc thông tin đơn giản việc viết vào Chương trình 12.10 sau minh họa cho cơng việc Ví dụ 12.10: Đọc thơng tin nhị phân // BinaryRead.cs: Doc thong tin tu file nhi phan namespace Programming_CSharp { using System; using System.IO; public class Tester { public static void Main( String[] args) { if ( args.Length < 1) { Console.WriteLine(“Phai nhap ten tap tin”); } else { FileStream myFile = new FileStream( args[0], FileMode.Open); BinaryReader brFile = new BinaryReader(myFile); // đọc liệu Console.WriteLine(“Dang doc tap tin ”); while (brFile.PeekChar() != -1) { Console.Write(“”, brFile.ReadInt32()); } Console.WriteLine(“ Doc xong”); brFile.Close(); 360 Các Lớp Cơ Sở NET ... trường phát triển 337 Các Lớp Cơ Sở NET Ngôn Ngữ Lập Trình C# Tìm hiểu lớp Framework Như biết có hàng ngàn lớp kiểu liệu khác bên thư viện sở Có thể tốn vài sách có kích thước giáo trình để nói tồn... chương trình, tốt ta dùng lớp FileInfo Hoặc khơng chắn cách sử dụng sử dụng lớp FileInfo Viết vào tập tin văn Cách tốt để nắm vững cách thức làm việc với tập tin bắt tay vào tìm hiểu chương trình. .. 199 5) mô tả chế sau: “Định nghĩa đến nhiều phụ thuộc đối tượng đối tượng thay đổi trạng thái, tất đối tượng khác phụ thuộc vào cảnh báo cập nhật cách tự động” Với chế này, đối tượng nói “Ở có