Giới thiệu về Isolated Storage cho ứng dụng .NET

Bài viết này nhắm giới thiệu về Isolated Storage cho các ứng dụng .NET và hướng dẫn bạn cách sử dụng Isolated Storage để lưu trữ thông tin cấu hình của ứng dụng.

Bạn đang viết một ứng dụng .NET, và bạn cần phải lưu trữ dữ liệu trong một tập tin, bạn sẽ phải băn khoăn về việc lựa chọn nơi để lưu trữ các tập tin đó, và phải giảm thiểu khả năng bị truy xuất bởi các chương trình khác, hoặc không may bị xóa bởi người dùng. Và .NET Fraemwork đã hỗ trợ cho các ứng dụng một nơi để lưu trữ dữ liệu mà không phải lo sợ bị đụng độ bởi các ứng dụng khác được gọi là Isolated Storage (bộ nhớ riêng nhất).

Với Isolated Storage, dữ liệu được lưu riêng biệt theo người dùng và hợp tập assembly (các tập tin dll). Khi sử dụng isolated storage, các ứng dụng có thể lưu trữ dữ liệu vào nơi lưu trữ duy nhất mà chỉ có nó mới có thể xác định được vị trí. Nơi lưu trữ dữ liệu là một thư mục mà ứng dụng có thể lưu trữ vào đó nhiều tập tin. Và ứng dụng mặc định có quyền đọc ghi với Isolated Storage, nên bạn không cần phải lo lắng khi đọc và ghi các tập tin vào kho lưu trữ này.

Ta có thể lưu trữ bất kỳ thông tin nào vào Isolated Storage, có thể là thông tin cấu hình của người dùng, có thể là trạng thái của ứng dụng. Tuy nhiên dung lượng của Isolated Storage của mỗi ứng dụng là hạn chế, tùy theo quy định của Administrators, và tùy theo mực độ tin cậy dành cho ứng dụng. Để có thể tạo hoặc truy xuất Isolated Storage, mã ứng dụng phải được cấp mức độ IsolatedStorageFilePermision tương ứng.

Các ứng dụng .NET đã có sẵn quyền hệ thống để truy xuất Isolated Storage, trừ phi chúng thực hiện các thao tác ảnh hưởng đến hệ thống. Khi đó chúng phải được cấp quyền để có thể thao tác.

Để biết được vị trí chính xác của Isolated Storage đối với từng hệ điều hành,  bạn có thể tham khảo tại địa chỉ này.

Phạm vi lưu trữ

Isolated Storage được phân chia thành các “Stores” (tạm gọi la kho lưu trữ), mỗi Store là một thư mục gốc có thể chứa nhiều tập tin và thư mục con khác. Các Stores được lưu ở các thư mục thuộc về người dùng hoặc của hệ thống. Bảng dưới đây cho biết các vị trị lưu trữ (location) của Isolated Storage và các yếu tố (evidence) dùng để xác định vị trí của duy nhất của Store.

solatedStorageScope enum
IsolatedStorageScopeKhái niệmMô tả
NoneKhông thuộc phạm vi nào
UserLocationThư mục đặc biệt LocalApplicationData
RoamingLocationThư mục đặc biệt ApplicationData. Chỉ tồn tại khi có quyền “User”.
MachineLocationThư mục đặt biệt CommonApplicationData
AssemblyEvidenceHợp tập gọi lệnh truy xuất Isolated Storage được dùng để tham chiếu.
DomainEvidenceĐịnh danh domain (thường là định danh của hợp tập chính của ứng dụng) được sử dụng làm tham chiếu.
ApplicationEvidenceĐịnh danh của ứng dụng được sử dụng để tham chiếu

Chúng ta sẽ tìm hiểu về các phối hợp để xác định vị trí của Isolated Storage trong ví dụ ở bên dưới đây.

Ví dụ về Isolated Storage

Ở đây tôi sẽ xây dựng một ứng dụng Windows Forms có chức năng lưu và đọc cấu hình truy xuất đến CSDL ở một tập tin xml được lưu ở Isolated Storage.

Tập tin XML của bạn sẽ có dạng:

<?xml version=""1.0"" encoding=""utf-8""?>
<Config>
	<Server></Server>
	<Database></Database>
	<Username></Username>
	<Password></Password>
</Config>

Và tập tin này sẽ được lưu trong Isolated Storage với tên là Setting.xml.

Giao diện chương trình được thiết kế như sau:

Hình 1. Giao diện người dùng

Người dùng khi chạy chương trình sẽ lấy thông tin kết nối bằng cách nhấn nút Load, trong trường hợp thông tin kết nối chưa được lưu vào Isolated Storage, chương trình sẽ thông báo cho người dùng biết. Trong trường hợp tập tin Setting.xml tồn tại trong Isolated Storage, chương trình sẽ dùng Linq-to-XML để đọc và hiển thị ra trên các text box.

Người dùng cũng có thể nhập thông tin mới vào các text box và nhấn nút Save để lưu lại. Chương trình sẽ kiểm tra thông tin đã được nhập đầy đủ, sau đó lưu tập tin vào Isolated Storage.
Tạo ứng dụng IsolatedStorageEx

Đầu tiên bạn hãy tạo một ứng dụng Windows Forms có tên là IsolatedStorageEx. Bạn hãy đổi tên Form mặc định thành MainForm.cs.

Giao diện của MainForm.cs được thiết kế giống Hình 1. Trong đó chúng sẽ có các control chính tương ứng như bảng dưới đây:

TênKiểu
tbServerTextBox
tbDatabaseTextBox
tbUsernameTextBox
tbPasswordTextBox
btLoadButton
btSaveButton

Trong MainForm.cs, chúng ta sẽ có một hằng số để lưu tên tập tin cấu hình:

private const string FileName = "Setting.xml";

Lớp Config

Chúng ta cần tạo một lớp có tên là Config để lưu tạm thông tin cấu hình như sau:

public class Config
        {
            public string Server { get; set; }
            public string Database { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
        }

Đọc dữ liệu từ Isolated Storage

Để sử dụng được Isolated Storage chúng ta cần tham chiếu để namespace System.IO.IsolatedStorage bằng cách sử dụng từ khóa using trong lớp MainForm

using System.IO.IsolatedStorage; v

Tiếp theo, bạn cần phải xử lý sự kiến click chuột của btLoad

private void btLoad_Click(object sender, EventArgs e)
        {
		…
	}

Đầu tiên chúng ta phải lấy được IsolatedStorageFile tương ứng với ứng dụng bằng câu lệnh:

var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User 
                | IsolatedStorageScope.Assembly, null, null)

Ở đây chúng ta thấy rằng, Store chúng ta muốn lấy sử dụng các evidence là User và Assembly, tức là tập tin Setting.xml sẽ được lưu trữ dựa trên thông tin của người dùng đang đăng nhập vào Windows và tên của hợp tập chính của chương trình chúng ta đang xây dựng.

Để xác định tập tin đã tồn tại hay không chúng ta sử dụng phương thức GetFileNames của lớp IsolatedStorageFile

if (isoStore.GetFileNames(FileName).Length > 0){..}

Khi đã xác định được tập tin nói trên tồn tại, chúng ta cần sử dụng một đối tượng StreamReader để hỗ trợ việc đọc tập tin như sau:

var reader = new StreamReader(new IsolatedStorageFileStream(FileName, FileMode.OpenOrCreate, isoStore))

Sau đó ta sẽ sử dụng Linq-to-XML để đọc tập tin và hiển thị chúng ở các textbox. Cài đặt đầy đủ của phương thức xử lý sự kiện Click của btLoad như sau:

private void btLoad_Click(object sender, EventArgs e)
        {
            using (var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User 
                | IsolatedStorageScope.Assembly, null, null))
            {
                if (isoStore.GetFileNames(FileName).Length > 0)
                {
                    using (var reader = new StreamReader(new IsolatedStorageFileStream(FileName, FileMode.OpenOrCreate, isoStore)))
                    {
                        var doc = XDocument.Load(reader);

                        var config = (from c in doc.Descendants("Config")
                                      select new Config
                                      {
                                          Server = (string)c.Element("Server"),
                                          Database = (string)c.Element("Database"),
                                          Username = (string)c.Element("Username"),
                                          Password = (string)c.Element("Password")
                                      }
                            ).SingleOrDefault();

                        tbDatabase.Text = config.Database;
                        tbServer.Text = config.Server;
                        tbUsername.Text = config.Username;
                        tbPassword.Text = config.Password;
                    }
                }
                else
                {
                    MessageBox.Show("Config file is not exists!");
                }
            }

        }

Lưu dữ liệu vào Isolated Storage

Tương tự như trên, chúng ta sẽ xử lý sự kiện Click của btSave, trong đó chúng ta sẽ sử dụng đối tượng StreamWriter để ghi tập tin cấu hình Setting.xml vào Isolated Storage của ứng dụng. Cài đặt cụ thể như sau:

private void btSave_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbDatabase.Text) || string.IsNullOrEmpty(tbServer.Text)
                || string.IsNullOrEmpty(tbUsername.Text) || string.IsNullOrEmpty(tbPassword.Text))
            {
                MessageBox.Show("Please input data before clicking on Save button!");
            }

            const string xmlString = @"<?xml version=""1.0"" encoding=""utf-8""?>
                        <Config><Server></Server><Database></Database>
                        <Username></Username><Password></Password></Config>";

            XDocument doc = XDocument.Parse(xmlString);

            var noteNode = doc.Elements("Config").Take(1);
            noteNode.Elements("Database").SingleOrDefault().Value = tbDatabase.Text;
            noteNode.Elements("Server").SingleOrDefault().Value = tbServer.Text;
            noteNode.Elements("Username").SingleOrDefault().Value = tbUsername.Text;
            noteNode.Elements("Password").SingleOrDefault().Value = tbPassword.Text;

            //Save
            using (var isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User 
                | IsolatedStorageScope.Assembly, null, null))
            {
                using (var writer = new StreamWriter(
                    new IsolatedStorageFileStream(FileName, FileMode.Create, isoStore)))
                {
                    doc.Save(writer);
                }
            }
        }

Chạy thử ứng dụng

Như vậy bạn đã hoàn thành xong công việc cài đặt cho ứng dụng, bạn hãy chạy thử ứng dụng, nhập một số thông tin kết nối và nhất nút Save. Nếu lưu thành công, khi mở lại ứng dụng, bạn nhấn nút Load và thông tin bạn lưu lúc trước sẽ được nạp lại đầy đủ. Mọi việc thật dễ dàng đúng không nào.

Kết luận

Isolated Storage là một công cụ mạnh giúp bạn có thể lưu các dữ liệu của ứng dụng mà không phải lo lắng nhiều về việc có các ứng dụng khác, hoặc người dùng sẽ vô tình làm hỏng dữ liệu. Isolated Storage không chỉ dành cho các ứng dụng Windows Forms, mà nó còn được sử dụng rất hiệu quả ở các loại ứng dụng khác. Đặc biệt, bạn sẽ không thể không sử dụng Isolated Storage nếu bạn lập trình với Windows Phone và Window Metro Application. Với hai loại ứng dụng vừa kể đến, tuy API của  Isolated Storage sẽ không giống với những gì chúng ta đang trải nghiệm, nhưng nguyên tắc hoạt động là tương đương. Như vậy bạn sẽ không cảm thấy lạ lẫm khi sử dụng chúng!