Tải bản đầy đủ (.pdf) (10 trang)

Các giải pháp lập trình CSharp- P49 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.62 MB, 10 trang )

371
Chương 9: File, thư mục, và I/O
"USAGE: WildcardTest [directory] [filterExpression]");
return;
}
DirectoryInfo dir = new DirectoryInfo(args[0]);
FileInfo[] files = dir.GetFiles(args[1]);

// Hiển thị tên và kích thước file.
foreach (FileInfo file in files) {
Console.Write("Name: " + file.Name + " ");
Console.WriteLine("Size: " + file.Length.ToString());
}
Console.ReadLine();
}
}
Nếu muốn tìm trong thư mục con, bạn cần sử dụng đệ quy. Nhiều mục trong chương sử dụng
kỹ thuật đệ quy để xử lý file, chẳng hạn 9.3 và 9.4.
11.
11.
Ki m tra hai file có trùng nhau hay khôngể
Ki m tra hai file có trùng nhau hay khôngể


Bạn cần so sánh nội dung của hai file và xác định chúng có trùng nhau hay
không.


Tính mã băm của mỗi file bằng lớp
System.Security.Cryptography.HashAlgorithm
rồi so sánh các mã băm.


Có nhiều cách để so sánh nhiều file. Ví dụ, có thể xét một phần của file xem có giống nhau,
hoặc đọc cả file so sánh từng byte. Cả hai cách trên đều đúng, nhưng trong một số trường hợp,
sử dụng mã băm thuận tiện hơn.
Một giải thuật băm sinh ra một dạng nhị phân đặc trưng (với kích thước nhỏ, thường khoảng
20 byte) cho file. Có khả năng hai file khác nhau có cùng mã băm, nhưng khả năng này hầu
như không xảy ra. Thực tế, cả những thay đổi nhỏ nhất (chẳng hạn, chỉ thay đổi một bit của
file nguồn) cũng có 50% khả năng thay đổi các bit của mã băm. Do đó, mã băm thường được
sử dụng để phát hiện dữ liệu bị sửa đổi (mã băm sẽ được đề cập chi tiết hơn trong chương 14).
Để tạo một mã băm, trước hết bạn phải tạo một đối tượng
HashAlgorithm
bằng phương thức
tĩnh
HashAlgorithm.Create
. Sau đó gọi
HashAlgorithm.ComputeHash
để nhận một mảng byte
chứa mã băm.
Ví dụ dưới đây đọc hai tên file từ đối số dòng lệnh và kiểm tra hai file này có trùng nhau hay
không:
using System;
using System.IO;
372
Chương 9: File, thư mục, và I/O
using System.Security.Cryptography;
public class CompareFiles {
private static void Main(string[] args) {
if (args.Length != 2) {
Console.WriteLine("USAGE: CompareFiles [fileName] " +
[fileName]");
return;

}
Console.WriteLine("Comparing " + args[0] + " and " + args[1]);
// Tạo đối tượng băm.
HashAlgorithm hashAlg = HashAlgorithm.Create();
// Tính mã băm cho file thứ nhất.
FileStream fsA = new FileStream(args[0], FileMode.Open);
byte[] hashBytesA = hashAlg.ComputeHash(fsA);
fsA.Close();
// Tính mã băm cho file thứ hai.
FileStream fsB = new FileStream(args[1], FileMode.Open);
byte[] hashBytesB = hashAlg.ComputeHash(fsB);
fsB.Close();
// So sánh mã băm.
if (BitConverter.ToString(hashBytesA) ==
BitConverter.ToString(hashBytesB)) {
Console.WriteLine("Files match.");
}else {
Console.WriteLine("No match.");
}
373
Chương 9: File, thư mục, và I/O

Console.ReadLine();
}
}
Các mã băm được so sánh bằng cách chuyển chúng thành chuỗi. Bạn cũng có thể duyệt qua
mảng và so sánh từng byte. Cách này nhanh hơn một ít, nhưng việc chuyển 20 byte thành
chuỗi không tốn nhiều chi phí nên không cần thiết.
12.
12.

Thao tác trên đ ng d n fileườ ẫ
Thao tác trên đ ng d n fileườ ẫ


Bạn cần lấy một phần đường dẫn file hoặc kiểm tra một đường dẫn file có ở
dạng chuẩn hay không.


Xử lý đường dẫn bằng lớp
System.IO.Path
. Bạn có thể sử dụng
Path.GetFileName
để lấy tên file từ đường dẫn,
Path.ChangeExtension
để thay đổi phần mở rộng của
đường dẫn, và
Path.Combine
để tạo đường dẫn đầy đủ mà không cần quan tâm
thư mục của bạn đã có ký tự phân cách thư mục(\) hay chưa.
Thường khó thao tác với các đường dẫn file vì có vô số cách để mô tả một thư mục. Ví dụ,
bạn có thể sử dụng đường dẫn tuyệt đối (C:\Temp), đường dẫn UNC
(\\MyServer\\MyShare\Temp), hoặc một trong các đường dẫn tương đối (C:\Temp\MyFiles\ \
hay C:\Temp\MyFiles\ \ \Temp).
Cách dễ nhất để xử lý các đường dẫn file là sử dụng các phương thức tĩnh của lớp
Path
để bảo
đảm có thông tin đúng. Ví dụ, đoạn mã sau trích tên file từ một đường dẫn file:
string filename = @" \System\MyFile.txt";
filename = Path.GetFileName(filename);
// filename bây giờ là "MyFile.txt".

Và đoạn mã sau sử dụng
Path.Combine
để thêm tên file vào đường dẫn thư mục:
string filename = @" \ \myfile.txt";
string fullPath = @"c:\Temp";
filename = Path.GetFileName(filename);
fullPath = Path.Combine(fullPath, filename);
// fullPath bây giờ là "c:\Temp\myfile.txt".
Cách này có ưu điểm là ký tự phân cách thư mục (\) sẽ tự động được thêm vào đường dẫn nếu
cần thiết.
Lớp
Path
cũng cung cấp các phương thức hữu ích sau đây để thao tác trên thông tin đường
dẫn:

ChangeExtension
—thay đổi phần mở rộng của file. Nếu phần mở rộng mới không được
chỉ định, phần mở rộng hiện tại sẽ bị xóa.
374
Chương 9: File, thư mục, và I/O

GetDirectoryName
—trả về thông tin của các thư mục nằm giữa ký tự phân cách thư mục
(\) đầu và cuối.

GetFileNameWithoutExtension
—tương tự như
GetFileName
, nhưng bỏ phần mở rộng.


GetFullPath
—không có tác dụng đối với đường dẫn tuyệt đối, và nó sử dụng thư mục
hiện hành để đổi một đường dẫn tương đối thành đường dẫn tuyệt đối. Ví dụ, nếu
C:\Temp\ là thư mục hiện hành, gọi
GetFullPath
cho file test.txt sẽ trả về C:\Temp\
test.txt.

GetPathRoot
—trả về chuỗi chứa thư mục gốc (ví dụ, "C:\"). Đối với đường dẫn tương
đối, nó trả về tham chiếu rỗng.

HasExtension
—trả về
true
nếu đường dẫn kết thúc với phần mở rộng.

IsPathRooted
—trả về
true
nếu đường dẫn là tuyệt đối,
false
nếu đường dẫn là tương
đối.

Trong hầu hết trường hợp, một ngoại lệ sẽ bị ném nếu bạn truyền đường dẫn
không hợp lệ cho một trong các phương thức này (chẳng hạn, đường dẫn có
chứa các ký tự không hợp lệ). Tuy nhiên, những đường dẫn không hợp lệ do
chứa các ký tự wildcard sẽ không làm sinh ra ngoại lệ.
13.

13.
Xác đ nh đ ng d n t ng ng v i m t file hay th m cị ườ ẫ ươ ứ ớ ộ ư ụ
Xác đ nh đ ng d n t ng ng v i m t file hay th m cị ườ ẫ ươ ứ ớ ộ ư ụ


Bạn có một đường dẫn (ở dạng chuỗi), và cần xác định nó tương ứng với một thư
mục hay một file.


Kiểm tra đường dẫn với phương thức
Directory.Exists

File.Exists
.
Cả hai lớp
System.IO.Directory

System.IO.File
đều có phương thức
Exists
.

Directory.Exists
—trả về
true
nếu đường dẫn (tương đối hoặc tuyệt đối) tương ứng
với một thư mục đang tồn tại.

File.Exists
—trả về

true
nếu đường dẫn tương ứng với một file đang tồn tại.
Sử dụng hai phương thức này, bạn có thể nhanh chóng xác định một đường dẫn có tương ứng
với một file hay thư mục hay không, như ví dụ sau:
using System;
using System.IO;
public class FileOrPath {
private static void Main(string[] args) {
foreach (string arg in args) {
375
Chương 9: File, thư mục, và I/O
Console.Write(arg);
if (Directory.Exists(arg)) {
Console.WriteLine(" is a directory");
}
else if (File.Exists(arg)) {
Console.WriteLine(" is a file");
}
else {
Console.WriteLine(" does not exist");
}
}
Console.ReadLine();
}
}
14.
14.
Làm vi c v i đ ng d n t ng đ iệ ớ ườ ẫ ươ ố
Làm vi c v i đ ng d n t ng đ iệ ớ ườ ẫ ươ ố



Bạn cần thiết lập thư mục làm việc hiện hành để có thể sử dụng đường dẫn
tương đối trong mã lệnh của bạn.


Sử dụng phương thức tĩnh
GetCurrentDirectory

SetCurrentDirectory
của lớp
System.IO.Directory
.
Đường dẫn tương đối tự động được diễn dịch dựa trên quan hệ với thư mục hiện hành. Bạn có
thể lấy thư mục hiện hành bằng phương thức
Directory.GetCurrentDirectory
hoặc thay đổi
nó bằng phương thức
Directory.SetCurrentDirectory
. Ngoài ra, bạn có thể sử dụng phương
thức tĩnh
GetFullPath
của lớp
System.IO.Path
để chuyển đường dẫn tương đối thành đường
dẫn tuyệt đối.
Dưới đây là một ví dụ minh họa:
using System;
using System.IO;
public class RelativeDirTest {
private static void Main() {

Console.WriteLine("Using: " + Directory.GetCurrentDirectory());
Console.WriteLine("The relative path 'file.txt' " +
"will automatically become: '" +
376
Chương 9: File, thư mục, và I/O
Path.GetFullPath("file.txt") + "'");
Console.WriteLine();
Console.WriteLine("Changing current directory to C:\\");
Directory.SetCurrentDirectory("C:\\");
Console.WriteLine("Now the relative path 'file.txt' " +
"will automatically become '" +
Path.GetFullPath("file.txt") + "'");
Console.ReadLine();
}
}
Kết xuất của ứng dụng này có thể như sau (nếu bạn chạy ứng dụng trong thư mục C:\Temp):
Using: C:\Temp
The relative path 'file.txt' will automatically become 'C:\Temp\file.txt'
Changing current directory to C:\
The relative path 'file.txt' will automatically become 'C:\file.txt'

Nếu sử dụng đường dẫn tương đối, bạn nên thiết lập thư mục làm việc khi bắt
đầu tương tác với file. Nếu không, có thể ảnh hưởng đến sự an toàn của hệ thống
nếu người dùng cố ý thay đổi thư mục làm việc để ứng dụng của bạn truy xuất
hoặc ghi đè file hệ thống.
15.
15.
T o file t mạ ạ
T o file t mạ ạ



Bạn cần tạo một file sẽ được đặt trong thư mục tạm của người dùng cụ thể và sẽ
có tên duy nhất, để nó không đụng độ với các file tạm được sinh ra bởi các
chương trình khác.


Sử dụng phương thức tĩnh
GetTempFileName
của lớp
System.IO.Path
, phương thức
này trả về một đường dẫn kết hợp đường dẫn đến thư mục tạm với một tên file
được tạo nhẫu nhiên.
Có nhiều cách để tạo file tạm. Trong các trường hợp đơn giản, bạn chỉ cần tạo một file trong
thư mục ứng dụng, có thể sử dụng một GUID hoặc một tem thời gian kết hợp với một giá trị
ngẫu nhiên làm tên file. Tuy nhiên, lớp
Path
hỗ trợ một phương thức giúp bạn đỡ tốn công
hơn. Nó sẽ tạo ra một file với tên duy nhất trong thư mục tạm của người dùng hiện hành,
chẳng hạn C:\Documents and Settings\username\Local Settings\Temp\tmpac9.tmp.
377
Chương 9: File, thư mục, và I/O
using System;
using System.IO;
public class TemporaryFile {
private static void Main() {
string tempFile = Path.GetTempFileName();
Console.WriteLine("Using " + tempFile);
FileStream fs = new FileStream(tempFile, FileMode.Open);
// (Ghi dữ liệu.)

fs.Close();
// Xóa file.
File.Delete(tempFile);
Console.ReadLine();
}
}
16.
16.
L y dung l ng đĩa còn tr ngấ ượ ố
L y dung l ng đĩa còn tr ngấ ượ ố


Bạn cần xét một ổ đĩa và xác định còn bao nhiêu byte trống.


Sử dụng hàm không-được-quản-lý
Win32 API

GetDiskFreeSpaceEx
, (hàm này
được khai báo trong
kernell32.dll
).
Không lớp nào trong các lớp về hệ thống file của .NET cho phép xác định dung lượng đĩa còn
trống. Tuy nhiên, bạn có thể dễ dàng lấy được thông tin này bằng hàm Win32 API
GetDiskFreeSpaceEx
. Hàm này sẽ trả về dung lượng tổng cộng, dung lượng còn trống, và
dung lượng còn trống có thể sử dụng được (nhà quản trị có thể sử dụng Disk Quota
Management để hạn chế dung lượng mà người dùng có thể sử dụng được).
378

Chương 9: File, thư mục, và I/O
Hình 9.2
Disk Quota Management
Ứng dụng Console dưới đây minh họa kỹ thuật này:
using System;
using System.Runtime.InteropServices;
public class GetFreeSpace {
[DllImport("kernel32.dll", EntryPoint="GetDiskFreeSpaceExA" )]
private static extern long GetDiskFreeSpaceEx(
string lpDirectoryName, out long lpFreeBytesAvailableToCaller,
out long lpTotalNumberOfBytes, out long lpTotalNumberOfFreeBytes);
private static void Main() {
long result, total, free, available;
result = GetDiskFreeSpaceEx("c:", out available, out total,
out free);
379
Chương 9: File, thư mục, và I/O
if (result != 0) {
Console.WriteLine("Total Bytes: {0:N}", total);
Console.WriteLine("Free Bytes: {0:N}", free);
Console.WriteLine("Available Bytes: {0:N}", available);
}
Console.ReadLine();
}
}
17.
17.
Hi n th các h p tho i fileể ị ộ ạ
Hi n th các h p tho i fileể ị ộ ạ



Bạn cần hiện các hộp thoại
Windows
chuẩn để mở, lưu file, và để chọn thư mục.


Sử dụng các lớp
OpenFileDialog
,
SaveFileDialog
, và
FolderBrowserDialog
thuộc
không gian tên
System.Windows.Forms
. Gọi phương thức
ShowDialog
để hiển thị
hộp thoại, xét giá trị trả về để xác định người dùng đã nhấn
OK
hay
Cancel
, và
lấy thông tin từ thuộc tính
FileName
hay
SelectedPath
.
.NET cung cấp các đối tượng bọc lấy nhiều hộp thoại Windows chuẩn, bao gồm các hộp thoại
dùng để mở và lưu file, và để chọn thư mục. Tất cả các lớp này đều thừa kế từ

System.Windows.Forms.CommonDialog
, bao gồm:

OpenFileDialog
—cho phép người dùng chọn một file. Tên file và đường dẫn có thể
được lấy từ thuộc tính
FileName
(hay tập hợp
FileNames
, nếu bạn cho phép chọn nhiều
file bằng cách thiết lập
Multiselect

true
). Ngoài ra, bạn có thể sử dụng thuộc tính
Filter
để chọn định dạng file và thiết lập thuộc tính
CheckFileExists
để kiểm tra tính
hợp lệ (xem hình 9.3).
[
380
Chương 9: File, thư mục, và I/O
Hình 9.3
OpenFileDialog

SaveFileDialog
—cho phép người dùng chỉ định một file mới. Tên file và đường dẫn có
thể được lấy từ thuộc tính
FileName

. Bạn có thể sử dụng thuộc tính
Filter
để chọn định
dạng file và thiết lập các thuộc tính
CreatePrompt

OverwritePrompt
để hiển thị thông
báo xác nhận khi người dùng chọn một file mới hay file đã tồn tại.

FolderBrowserDialog
—cho phép người dùng chọn (và tạo) một thư mục. Đường dẫn đã
chọn có thể được lấy từ thuộc tính
SelectedPath
. Ngoài ra, bạn có thể thiết lập thuộc
tính
ShowNewFolderButton
để hiển thị nút Make New Folder (xem hình 9.4).
Hình 9.4
FolderBrowserDialog
Khi sử dụng
OpenFileDialog
hay
SaveFileDialog
, bạn cần thiết lập chuỗi lọc (chỉ định các
phần mở rộng được phép). Chuỗi lọc được phân cách bởi ký tự "|" theo định dạng: "[Nhãn] |
[Danh sách các phần mở rộng được phân cách bởi dấu chấm phẩy] | [Nhãn] | [Danh sách các
phần mở rộng được phân cách bởi dấu chấm phẩy] | ". Bạn cũng có thể thiết lập thuộc tính
Title
(tiêu đề) và

InitialDirectory
(thư mục ban đầu).
Ứng dụng dưới đây cho phép người dùng nạp tài liệu vào một
RichTextBox
, sửa nội dung, và
lưu tài liệu đã được sửa (sử dụng lớp
OpenFileDialog

SaveFileDialog
để mở và lưu tài
liệu).
using System;
using System.Drawing;
using System.Windows.Forms;
public class SimpleEditForm : System.Windows.Forms.Form {
private System.Windows.Forms.MenuItem mnuFile;
private System.Windows.Forms.MenuItem mnuOpen;

×