Chương 7 QUẢN LÝ BỘ NHỚ VÀ TẬP TIN
7.3 XỬ LÝ TẬP TIN
7.3.4 Đ ọc và ghi d ữ liệ u vào tậ p tin
Mỗi tập tin đang mở có một con trỏ tập tín xác định byte kê tiếp sẽ được đọc hoặc ghi. Khi một tập tin mở lần đầu tiên, hệ thống thiết lập con trỏ tập tin tại vị trí đầu tập tin.
Mỗi khi đọc hoặc ghi vào một byte, con trỏ tập tin tự động dịch chuyển. Đ ể thay đổi vị trí này, ta dùng hàm SetFilePointer.
DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
Trường hFile là handle của tập tin chứa con trỏ tập tin cần di chuyển. Handle này cắn được tạo dưới dạng truy cập GENERICJR.EAD hoặc GENERIC_WRITE.
Trường lDistanceToMove và lpDistanceToMoveHigh xác định số byte con trỏ cắn dịch chuyển. Nêu lpDistanceToMoveHigh bằng NULL, 32-bit thấp của IDistanceToMove xác định sô byte cần di dời con trỏ. NgưỢc lại, hai trường ưên thiết lập một giá trị 64-bit (không dấu) thể hiện sô byte cần di dời con trỏ.
WINDOWS
Trường dwMoveMethod xác định điểm gốc mà con trỏ cần di dời. N êu trường này bằng FILE BEGIN, điểm gốc là điểm đẩu tiên (byte thứ 0) của tập tin. Nêu là
FILE_CURRENT, điểm gốc là vị trí hiện tại của con trỏ. Và FILE_END xác định điểm gốc là vị trí cuối hiện tại của tập tin.
Nêu thành công, và lpDistanceToMoveHigh bằng NULL, giá trị ưả v ề là DWORD thấp của con trỏ tập tin. Nêu lpDistanceToMoveHigh khác NULL, hàm trả v ề DWORD thấp của con trỏ tập tin, và trỏ trường này đến DWORD cao của con trỏ tập tin.
Nêu hàm thất bại và lpDistanceToMoveHigh bằng NULL, giá trị trả v ề là OxFFFFFFFF. Đ ể biết thêm thông tin lỗi, ta dùng ham GetLastError. Nêu hàm trả về OxFFFFFFFF và lpDistanceToMoveHigh, có thể hàm thành công hoặc thất bại, cẩn phải gọi hàm GetLastError để xác định. Đoạn chương trình sau trình bày vấn đề này :
/ * Trường hợp 1: G ọi hàm với IpDistanceToMoveHiqh == NULL * /
/ * CÔ gắng di chuyển con trỏ tập tin c ủ a hFile m ộ t đoạn */
dwPtr = SetFilePointer(hFile, LDistance, NULL, FILE_BEGIN);
if (dwPtr == OxFFFFFFFF) // Kiểm tra thất bại
{
dwError = GetLastErrorO ; //N hận mã lỗi . . . / / X ử lý lỗi
} // Cuối phần x ử lý lỗi
/* Trường hợp 2: G ọi hàm với IpDistanceToMoveHigh != NULL */
/* CỐ gắng di chuyển con t r đ tập tín hFile m ột đoạn dài */
dwPtrLow = SetFilePointer(hFile, lDistLow, & lDistHigh, FILE_BEGIN);
/* Kiểm tra thất bại */
if (dwPtrLow==OxFFFFFFFF&&(dwEiror=GetLastError())!=NO_ERROR) {
/ / X ử l ý lỗi
//...
} // Cuối phần x ử lý lỗi
WINDOWS
Đ ể di chuyển tiến, ta thiết lập độ dịch chuyển một giá trị dương. NgƯỢc lại, thiết lập giá trị âm đ ể di chuyển lùi con trỏ tập Un. Nêu giá trị con trỏ tập tin sau khi dịch chuyển âm, hàm thất bại, và mã lỗi mà hàm G etlastError trả về là ERROR_NEGATIVE_SEEK.
Nêu muốn di chuyển con trỏ đến cuối tập tin đ ể ghi tiếp, ta cũng có thể dừng hàm SetEndOfFile.
BOOL SetEndOfFUe(HANDLE hFüe);
Trường hFile là handle của tập tin cần di chuyển con trỏ đến cuối tập tín cần được tạo với dạng truy cập GENERAL_WRITE. Nêu thành công, hàm trả v ề giá trị khác 0. NgưỢc lại, giá trị tra về là 0.
Hàm ReadFile đọc dữ liệu từ một tập tin, từ điểm xác định bởi con trỏ tập tin. Sau khi đpr, rnn trỏ tập tin rlịrh rhnyển mộr đoạn ứng với sô hytp thật sự đ ọ r đưỢr. Tương tự, đ ể ghi vào tập tin ta dùng hàm WriteFile.
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD
nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD
nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
Handle tập tin hFile cần được tạo với dạng truy cập GENERAL_READ hoặc GENERAL_WRITE.
Trường lpBuffer trỏ đến vùng nhớ đệm nhận dữ liệu đọc từ tập tin, hay chứa dữ liệu cắn ghi. Trường nNumberOfBytesToRead xác định sô byte cắn đọc. Trường
lpNumberOfBytesRead trỏ đến các byte đọc được. Hàm ReadFile thiết lập giá ttị này bằng 0 trước khi thực hiện các thao tác khác đ ể kiểm ưa lỗi.
Trường nNumberOfBytesTo Write xác định số byte cần ghi. Nêu trường này bằng 0, hàm không ghi dữ liệu, nhưng vẫn được gọi thực hiện. Trường IpNumberOfBytesWritten xác định sô byte ghi được, trường này cũng được hàm WriteFile thiết lập vể 0 trước khi thực hiện các thao tác khác để kiểm tra lỗi.
Cuối cùng, trường lpOverlapped trỏ đến cấu trúc OVERLAPPED. Nêu tập tin được mở với cờ FILE_FLAG_OVERLAPPED, giá trị này phải khác NULL. Để đơn giản ta thiết lập giá trị bằng NULL, hàm sẽ đọc (ghi) tập tin từ vị trí con ưỏ hiện tại và hàm chỉ ư ả kết quả v ề sau khi đọc (ghi) xong.
Hàm ReadFile sẽ dừng với một sô lý do sau : thao tác ghi hoàn tất cuối đường ống ghi, đã đọc hết sô byte yêu cầu, hoặc xảy ra lỗi khi đọc.
Nêu thành công, các hàm trả v ề giá trị khác 0. Ngược lại, giá trị trả v ề bằng 0.
NGÔN NGỮ LẬP TRÌNH WINDOWS