Các lớp này cho phép ứng dụng ghi dữ liệu vào một file trong thư mục của một người dùng cụ thể mà không cần được cấp phép truy xuất trực tiếp ổ đĩa cứng cục bộ.. .NET Framework hỗ trợ kh
Trang 1private System.Windows.Forms.MenuItem mnuExit;
private System.Windows.Forms.RichTextBox rtDoc;
// (Bỏ qua phần mã designer.)
private void mnuOpen_Click(object sender, System.EventArgs e) {
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "Rich Text Files (*.rtf)|*.RTF|" +
"All files (*.*)|*.*";
dlg.CheckFileExists = true;
dlg.InitialDirectory = Application.StartupPath;
if (dlg.ShowDialog() == DialogResult.OK) {
rtDoc.LoadFile(dlg.FileName);
rtDoc.Enabled = true;
}
}
private void mnuSave_Click(object sender, System.EventArgs e) {
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "RichText Files (*.rtf)|*.RTF|Text Files (*.txt)|
*.TXT" +
"|All files (*.*)|*.*";
dlg.CheckFileExists = true;
dlg.InitialDirectory = Application.StartupPath;
if (dlg.ShowDialog() == DialogResult.OK) {
rtDoc.SaveFile(dlg.FileName);
}
}
private void mnuExit_Click(object sender, System.EventArgs e) {
this.Close();
}
Trang 218. S d ng không gian l u tr riêng S d ng không gian l u tr riêng ử ụ ử ụ ư ữ ư ữ
Bạn cần lưu dữ liệu vào file, nhưng ứng dụng của bạn không được cấp
FileIOPermission để sử dụng ổ đĩa cứng.
Sử dụng các lớp IsolatedStorageFile và IsolatedStorageFileStream thuộc không
gian tên System.IO.IsolatedStorage Các lớp này cho phép ứng dụng ghi dữ liệu vào một file trong thư mục của một người dùng cụ thể mà không cần được cấp phép truy xuất trực tiếp ổ đĩa cứng cục bộ.
.NET Framework hỗ trợ không gian lưu trữ riêng, tức là cho phép bạn đọc và ghi vào hệ thống file ảo của người dùng cụ thể mà CLR quản lý Khi bạn tạo các file lưu trữ riêng, dữ liệu tự
động được lưu vào một nơi duy nhất trong đường dẫn profile của người dùng (thông thường
đường dẫn này có dạng C:\Documents and Settings\[username]\Local Settings\Application Data\IsolatedStorage\ [guid_identifier]).
Một lý do để sử dụng không gian lưu trữ riêng là trao cho một ứng dụng có-độ-tin cậy-một-phần có khả năng hạn chế khi lưu trữ dữ liệu (xem mục 13.1 để có thêm thông tin về mã lệnh
có-độ-tin-cậy-một-phần) Ví dụ, chính sách bảo mật CLR mặc định cấp cho mã lệnh cục bộ có
FileIOPermission không hạn chế, tức là có quyền đọc và ghi bất kỳ file nào Mã lệnh thực thi
từ một máy chủ ở xa trên mạng Intranet cục bộ tự động được cấp ít quyền hơn—thiếu mất
FileIOPermission, nhưng có IsolatedStoragePermission, tức là có khả năng sử dụng không gian lưu trữ riêng (chính sách bảo mật cũng hạn chế dung lượng tối đa có thể được sử dụng trong không gian lưu trữ riêng) Một lý do khác để sử dụng không gian lưu trữ riêng là bảo vệ
dữ liệu tốt hơn Ví dụ, đối với dữ liệu trong không gian lưu trữ riêng của một người dùng, những người dùng khác không phải là nhà quản trị sẽ không được quyền truy xuất.
Đoạn mã dưới đây minh họa cách truy xuất không gian lưu trữ riêng:
using System;
using System.IO;
using System.IO.IsolatedStorage;
public class IsolatedStoreTest {
private static void Main() {
// Tạo không gian lưu trữ riêng cho người dùng hiện hành
IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForAssembly();
Trang 3store.CreateDirectory("MyFolder");
// Tạo một file trong không gian lưu trữ riêng
Stream fs = new IsolatedStorageFileStream(
"MyFile.txt", FileMode.Create, store);
StreamWriter w = new StreamWriter(fs);
// Ghi file như bình thường
w.WriteLine("Test");
w.Flush();
fs.Close();
Console.WriteLine("Current size: " + store.CurrentSize.ToString()); Console.WriteLine("Scope: " + store.Scope.ToString());
Console.WriteLine("Contained files include:");
string [] files = store.GetFileNames("*.*");
foreach (string file in files) {
Console.WriteLine(file);
}
Console.ReadLine();
}
}
Theo mặc định, mỗi không gian lưu trữ riêng được tách biệt bởi người dùng và assembly Điều này có nghĩa là khi cùng một người chạy cùng một ứng dụng, ứng dụng này sẽ truy xuất
dữ liệu trong cùng không gian lưu trữ riêng Tuy nhiên, bạn có thể tách biệt thêm bởi miền ứng dụng để nhiều thể hiện của cùng một ứng dụng nhận các không gian lưu trữ riêng khác nhau, như ví dụ sau:
// Truy xuất không gian lưu trữ riêng của người dùng
// và assembly hiện tại (tương tự ví dụ trên)
store = IsolatedStorageFile.GetStore(IsolatedStorageScope.User |
IsolatedStorageScope.Assembly, null, null);
// Truy xuất không gian lưu trữ riêng của người dùng, assembly,
// và miền ứng dụng hiện hành Nói cách khác, dữ liệu này chỉ được
Trang 4// truy xuất bởi thể hiện hiện tại của ứng dụng.
store = IsolatedStorageFile.GetStore(IsolatedStorageScope.User |
IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain,
null, null);
File được lưu trữ như một phần profile của người dùng, vì vậy người dùng có thể truy xuất
các file này từ bất kỳ máy nào trong mạng LAN nếu roaming profile3 đã được cấu hình (trong trường hợp này, phải thiết lập cờ IsolatedStorageFile.Roaming khi tạo không gian lưu trữ)
Bằng cách để NET Framework và CLR cung cấp các mức cách ly, bạn không phải duy trì sự
tách biệt giữa các file, và không phải lo việc không hiểu rõ cơ chế làm việc sẽ gây mất dữ liệu quan trọng.
19. Theo dõi h th ng file đ phát hi n thay đ i Theo dõi h th ng file đ phát hi n thay đ i ệ ố ệ ố ể ể ệ ệ ổ ổ
Bạn cần phản ứng khi hệ thống file thay đổi tại một đường dẫn cụ thể (chẳng
hạn sửa hay tạo file).
Sử dụng thành phần System.IO.FileSystemWatcher, chỉ định file hoặc đường dẫn
cần theo dõi, và thụ lý các sự kiện Created, Deleted, Renamed, và Changed.
Khi liên kết nhiều ứng dụng và các quá trình nghiệp vụ, thường cần tạo một chương trình thụ động và chỉ trở nên tích cực khi một file được tạo ra hoặc bị thay đổi Bạn có thể tạo kiểu chương trình thế này bằng cách quét định kỳ qua một thư mục, nhưng lại gặp phải vấn đề cân bằng Quét càng thường xuyên, càng tốn tài nguyên hệ thống Quét càng ít, càng lâu phát hiện được thay đổi Cách tiện nhất là sử dụng lớp FileSystemWatcher để phản ứng trực tiếp các sự
kiện file của Windows.
Để sử dụng FileSystemWatcher, bạn phải tạo một thể hiện và thiết lập các thuộc tính sau:
• Path—chỉ định đường dẫn cần theo dõi.
• Filter—chỉ định kiểu file cần theo dõi.
• NotifyFilter—chỉ định kiểu thay đổi cần theo dõi.
FileSystemWatcher sinh ra bốn sự kiện chính: Created, Deleted, Renamed, và Changed Các sự kiện này cung cấp thông tin qua đối số FileSystemEventArgs, bao gồm tên file (Name), đường dẫn đầy đủ (FullPath), kiểu thay đổi (ChangeType) Sự kiện Renamed cung cấp thể hiện
RenamedEventArgs dẫn xuất từ FileSystemEventArgs, và thêm thông tin về tên file ban đầu (OldName và OldFullPath) Nếu cần, bạn có thể vô hiệu các sự kiện này bằng cách thiết lập thuộc tính FileSystemWatcher.EnableRaisingEvents là false Dễ dàng thụ lý các sự kiện
Created, Deleted, và Renamed Nhưng nếu muốn sử dụng sự kiện Changed, bạn cần sử dụng thuộc tính NotifyFilter để chỉ định kiểu thay đổi cần theo dõi Bằng không, chương trình của bạn có thể bị sa lầy bởi một loạt các sự kiện khi file bị thay đổi.
3Roaming profile được tạo bởi người quản trị hệ thống và được lưu trữ trên một server Profile này có sẵn mỗi khi bạn đăng nhập vào bất kỳ máy tính nào trên mạng Bất cứ thay đổi nào cũng khiến roaming profile được cập nhật lại trên server
Trang 5System.IO.NotifyFilters: Attributes, CreationTime, DirectoryName, FileName, LastWrite,
LastAccess, Security, và Size.
Ví dụ dưới đây thụ lý sự kiện Created và Deleted Và thử nghiệm các sự kiện này bằng cách tạo ra một file thử nghiệm.
using System;
using System.IO;
using System.Windows.Forms;
public class FileWatcherTest {
private static void Main() {
// Cấu hình FileSystemWatcher
FileSystemWatcher watch = new FileSystemWatcher();
watch.Path = Application.StartupPath;
watch.Filter = "*.*";
watch.IncludeSubdirectories = true;
// Đăng ký các phương thức thụ lý sự kiện
watch.Created += new FileSystemEventHandler(OnCreatedOrDeleted);
watch.Deleted += new FileSystemEventHandler(OnCreatedOrDeleted);
watch.EnableRaisingEvents = true;
Console.WriteLine("Press Enter to create a file.");
Console.ReadLine();
if (File.Exists("test.bin")) {
File.Delete("test.bin");
}
FileStream fs = new FileStream("test.bin", FileMode.Create);
fs.Close();
Console.WriteLine("Press Enter to terminate the application.");
Console.WriteLine();
Console.ReadLine();
}
Trang 6// Phát sinh khi một file mới được tạo ra
// trong thư mục cần theo dõi
private static void OnCreatedOrDeleted(object sender,
FileSystemEventArgs e) {
// Hiển thị thông báo
Console.WriteLine("\tNOTIFICATION: " + e.FullPath +
"' was " + e.ChangeType.ToString());
Console.WriteLine();
}
}
20. Truy xu t c ng COM Truy xu t c ng COM ấ ổ ấ ổ
Bạn cần gửi dữ liệu trực tiếp đến một cổng tuần tự (serial port).
Win32 API cung cấp các hàm không-được-quản-lý trong thư viện kernell32.dll
để trực tiếp đọc và ghi các byte đến cổng tuần tự Bạn có thể nhập các hàm này
vào ứng dụng hoặc sử dụng Microft Communications ActiveX control (MSComm.ocx—có trong Microsoft Visual Studio 6).
.NET không cung cấp bất kỳ giao diện được-quản-lý nào để thao tác với các cổng tuần tự Do
đó, những ai cần chức năng này sẽ phải làm việc với các cơ chế tương đối phức tạp.
Một hướng giải quyết là tạo một vỏ bọc .NET cho Microsoft Communications Control (MSComm.ocx) Điều kiểm này cung cấp một mô hình đối tượng mức-cao để làm việc với cổng tuần tự Tuy nhiên, bạn phải thu lấy điều kiểm này thông qua Visual Studio 6 (bạn có thể chỉ chọn cài đặt các thành phần ActiveX khi cài đặt Visual Studio 6, tốn khoảng 5MB) Để có thêm thông tin, bạn hãy tham khảo tài liệu Visual Studio 6.
Một hướng giải quyết khác là nhập các hàm API từ thư viện kernell32.dll Cần cẩn thận khi sử dụng phương pháp này vì bạn phải sử dụng đúng kiểu dữ liệu C# và duy trì layout của các cấu trúc bộ nhớ May mắn là, vấn đề này đã được Justin Harrell (jharrell@aciss.com) giải quyết với
một lớp C# tùy biến có tên là ComPort Mã lệnh của lớp này khá dài, bạn hãy xem trong đĩa
CD đính kèm.
Bạn có thể thêm lớp ComPort vào ứng dụng của bạn và sử dụng đoạn mã sau để tương tác với
một cổng COM.
ComPort port = new ComPort();
try {
// Cấu hình cho cổng
Trang 7port.Parity = 0;
port.PortNum = 1;
port.ReadTimeout = 10;
port.StopBits = 1;
port.ByteSize = 1;
// Mở cổng
port.Open();
// Ghi dữ liệu
port.Write(new byte[1]);
// Đóng cổng
port.Close();
}catch (ApplicationException err) {
Console.WriteLine(err.Message);
}
Trang 9Chương 10:CƠ SỞ DỮ LIỆU