Hướng dẫn thao tác file DBF bằng C# 1 Định nghĩa cấu trúc lưu trữ main header và field header Ta lưu trữ cấu trúc của phần main header và field header vào hai lớp CMainHeader và CfieldHeader (ở đây chỉ khai báo các trường có sử dụng mà không khai báo hết các trường trong các header). class CMainHeader { public byte version; public byte year, month, day; public int num_of_record; public char header_length; public char record_length; public byte[] reserved; public CMainHeader(){ } } class CFieldHeader { public byte[] field_name; public byte type; public int record_offset; public byte field_length; public byte decimal_number; public byte[] reserved; public CFieldHeader(){ } } 2 Thao tác đọc main header và field header Ta hiệu chỉnh lại constructor để thực hiện xây dựng main header và field header từ chuỗi byte tương ứng. Dữ liệu đầu vào là chuỗi byte đọc được từ stream, ta xử lí chuyển byte thành dạng dữ liệu phù hợp với từng trường. class CMainHeader { public byte version; public byte year, month, day; public int num_of_record; public char header_length; public char record_length; public byte[] reserved; // Input: chuỗi byte đọc từ stream public CMainHeader(byte[] buf) { version = buf[0]; year = buf[1]; month = buf[2]; day = buf[3]; num_of_record = BitConverter.ToInt32(buf, 4); header_length = BitConverter.ToChar(buf, 8); record_length = BitConverter.ToChar(buf, 10); reserved = new byte[20]; Array.Copy(buf, 12, reserved, 0, 20); } } class CFieldHeader { public byte[] field_name; public byte type; public int record_offset; public byte field_length; public byte decimal_number; public byte[] reserved; public CFieldHeader(byte [] buf) { field_name = new byte[11]; Array.Copy(buf, 0, field_name, 0, 11); type = buf[11]; record_offset = BitConverter.ToInt32(buf, 12); field_length = buf[16]; decimal_number = buf[17]; reserved = new byte[14]; Array.Copy(buf, 18, reserved, 0, 14); } } 3 Tổng hợp xử lí Khai báo trước hai biến chứa main header và mảng field header CMainHeader header; CFieldHeader []field_header; Xây dựng hàm xử lí đọc header file DBF //Input: tên file DBF public void ReadFileDBF(string filename) { // Mở file DBF System.IO.FileStream filestream = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); System.IO.BinaryReader bReader = new System.IO.BinaryReader(filestream); // Chỉ định vị trí bắt đầu đọc dữ liệu từ stream bReader.BaseStream.Position = 0; // Đọc dữ liệu vào buffer tạm và phân tích thành các thành phần trong CMainHeader byte[] buffer = new byte[32]; bReader.Read(buffer, 0, 32); header = new CMainHeader(buffer); // Tính số field, đọc dữ liệu vào buffer tạm và phân tích thành các thành phần trong CFieldHeader int nField = (header.header_length - 1) / 32 - 1; field_header = new CFieldHeader[nField]; for (int i = 0; i < nField; i++) { bReader.Read(buffer, 0, 32); field_header[i] = new CFieldHeader(buffer); } // Đóng file DBF bReader.Close(); filestream.Close(); } 4 Kĩ thuật khác Chuyển từ byte sang string Ví dụ: chuyển trường field_name kiểu byte[] thành string string res = System.Text.Encoding.ASCII.GetString(field_header[i].field_name); HƯỚNG DẪN TẠO GIAO DIỆN ĐỒ HOẠ BẰNG MFC CHO BÀI TẬP 1 Các bước sau sẽ sử dụng đối tượng ListControl của MFC để tạo bảng xuất dữ liệu cho bài tập thao tác trên tập tin DBF. Bước 1 : Tạo một dialog MFC dựa trên và các điều khiển Chọn loại project: MFC AppWizard (exe) -> Chọn loại ứng dụng Dialog based. Nhấn Finish. Thêm các điều khiển: một nút Open… để mở file và một ListControl Chọn thuộc tính cho ListControl Đặt tên biến cho (dùng Class Wizard) ListControl: m_lstTable. Thêm phần đọc và xử lý file dbf đã viết (yêu cầu cơ bản) vào project. Bước 2 : Sử dụng hộp thoại FileDialog để mở tập tin DBF. Nhấn double click vào nút Open để tạo handler, nhấn OK để soạn thảo mã lệnh, nhập đoạn mã sau: { CFileDialog fd(true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "DBF Files(*.dbf)|*.dbf|All files|*.*|", this); if (fd.DoModal() == IDOK) { CString s= fd.GetFileName(); // Đọc nội dung file dbf bằng các hàm đã viết // nếu tham số filename kiểu char * thì thực hiện ép chuỗi: // DocDBF((LPTSTR)(LPCTSTR)s); } } Bước 3: Tạo các cột dữ liệu cho bảng dựa vào mảng header field. Giả sử các field header có cấu trúc DBF_FIELD_HEADER và đọc được nNum trường dữ liệu. Thêm hàm SetColumns vào lớp CTableDlg (nhấn chuột phải lên lớp CTableDlg và chọn Add Member Function…) với nội dung sau void CTableDlg::SetColumns(DBF_HEADER_FIELD *fields, int nNum) { for (int i= 0; i< nNum; i++) { m_lstTable.InsertColumn(i, fields[i].FieldName); m_lstTable.SetColumnWidth(i, fields[i].length * 5); } } Bước 4: Đưa các mẫu dữ liệu vào bảng. Giả sử mỗi lần đọc 1 record đưa vào buf, dựa vào mảng DBF_FIELD_HEADER *fields để tách các giá trị dữ liệu thành các trường, mỗi trường lưu vào một phần từ của mảng CString *s, hàm sau đây thêm một dòng dữ liệu vào bảng void CTableDlg::InsertData(CString *s, int nNum) { LVITEM lvi; lvi.mask = LVIF_TEXT; lvi.iItem= m_lstTable.GetItemCount(); lvi.iSubItem = 0; lvi.pszText = (LPTSTR)(LPCTSTR)s[0]; m_lstTable.InsertItem(&lvi); for (int i= 1; i< nNum; i++) { lvi.iSubItem = i; lvi.pszText = (LPTSTR)(LPCTSTR)s[i]; m_lstTable.SetItem(&lvi); } } Bước 5: Xoá dữ liệu của bảng (dùng khi cần mở tập tin mới) void CTableDlg::ClearData() { m_lstTable.DeleteAllItems(); int n= m_lstTable.GetHeaderCtrl()->GetItemCount(); for(;n>0;n ) m_lstTable.DeleteColumn(0); } . header file DBF //Input: tên file DBF public void ReadFileDBF(string filename) { // Mở file DBF System.IO.FileStream filestream = new System.IO.FileStream(filename, System.IO.FileMode.Open,. Hướng dẫn thao tác file DBF bằng C# 1 Định nghĩa cấu trúc lưu trữ main header và field header Ta lưu trữ cấu trúc. "DBF Files(*.dbf)|*.dbf|All files|*.*|", this); if (fd.DoModal() == IDOK) { CString s= fd.GetFileName(); // Đọc nội dung file dbf bằng các hàm đã viết // nếu tham số filename