写了个win32函数对文件操作的程序,这里记录一下。
FileHandle.h
#pragma once
#define MAX_RECORD 100
typedef struct _PhoneRecord
{
char id[4]; // id
char name[16]; // name
char phoneNumber[20]; // 电话号码
unsigned short int state; // 电话状态(0未接、1已接、2已拨)
char oTime[20]; // 发生时间
char usedTime[8]; // 通话时长
char other[32]; // 扩展用
}PhoneRecord;
#define FILE_NAME _T("record.log")
class CFileHandle
{
public:
CFileHandle(void);
virtual ~CFileHandle(void);
CString FileName; // 文件名称
BOOL CreateARecord(PhoneRecord record); // 新增一条记录
BOOL DeteleARecord(char* id); // 删除一条记录
BOOL DeteleARecord(int n); // 删除第n条记录
BOOL DeleteAllRecords(); // 删除所有记录
BOOL ModifyARecord(char* id, PhoneRecord record); // 修改一条记录
BOOL ModifyARecord(int n, PhoneRecord record); // 修改第n条记录
BOOL ReadARecord(PhoneRecord& record); // 读取一条记录
BOOL ReadARecord(int n, PhoneRecord& record); // 读取第n条记录
BOOL CString2Char(CString str, char* buf, int bufInLen, int& bufOutLen); // CString转char*
BOOL Char2CString(char* buf, int bufLen, CString& str); // char*转CString
BOOL GetRecordCount(DWORD& size); // 获取record总条数
BOOL FindAEmptyRecord(char* id); // 找出最近一条空记录(以phoneNumber为空判断为空记录)
BOOL InsertARecord(PhoneRecord record); // 插入一条新记录到文件中(插入到空的record中,无空record则新增一条)
};
FileHandle.cpp
#include "StdAfx.h"
#include "FileHandle.h"
CFileHandle::CFileHandle(void)
{
}
CFileHandle::~CFileHandle(void)
{
}
//********************************************************************
// Function : CreateARecord
// Description : 新增一条记录
// Input : record : PhoneRecord结构体
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::CreateARecord(PhoneRecord record)
{
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
//MessageBox(L"创建test.txt文件失败");
::OutputDebugStringW(L"--- CreateARecord create file fail ---\r\n");
return FALSE;
}
// point to file end
//BOOL ok = SetEndOfFile(hFile);
DWORD point = SetFilePointer(hFile, 0, 0, FILE_END);
/*if(!point){
::OutputDebugStringW(L"--- CreateARecord point to file end fail ---\r\n");
return FALSE;
}*/
// WriteFile
DWORD dwWritenSize = 0;
BOOL ok = WriteFile(hFile, &record, sizeof(record), &dwWritenSize, NULL);
if(ok){
// flush the data to file
ok = FlushFileBuffers(hFile);
//AfxMessageBox(L"写入文件成功");
}
else{
//MessageBoxW(NULL, L"写入文件失败", L"提示", 0);
::OutputDebugStringW(L"--- CreateARecord write a new record to file fail ---\r\n");
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return ok;
}
//********************************************************************
// Function : DeteleARecord
// Description : 删除一条记录,删除后的记录只有id值存在,其他为空。只要电话号码为空则为空记录
// Input : id : n的取值大于等于0
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::DeteleARecord(char *id)
{
if(id == NULL) return FALSE;
PhoneRecord record;
memset(&record, 0, sizeof(record));
memcpy(record.id, id, strlen(id));
BOOL ok = ModifyARecord(id, record);
return true;
}
//********************************************************************
// Function : DeteleARecord
// Description : 删除第n条记录,删除后的记录只有id值存在,其他为空。只要电话号码为空则为空记录
// Input : id : n的取值大于等于0
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::DeteleARecord(int n)
{
if(n < 0) return FALSE;
PhoneRecord record;
memset(&record, 0, sizeof(record));
// int to char
char *p = itoa(n, record.id, 10);
if(p == NULL) return FALSE;
BOOL ok = ModifyARecord(n, record);
return true;
}
//********************************************************************
// Function : DeleteAllRecords
// Description : 删除所有记录
// Input : NONE
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::DeleteAllRecords()
{
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_WRITE, 0, NULL, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
::OutputDebugStringW(L"--- DeleteAllRecords create file fail ---\r\n");
return FALSE;
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return TRUE;
}
//********************************************************************
// Function : ModifyARecord
// Description : 修改一条记录
// Input : id : n的取值大于等于0
// Input : record : PhoneRecord结构体
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::ModifyARecord(char *id, PhoneRecord record)
{
// get file record size
DWORD dwSize;
BOOL ok = GetRecordCount(dwSize);
if(!ok) return FALSE;
// read a record
PhoneRecord recordT;
for(unsigned int i=0; i<dwSize; i++){
memset(&recordT, 0, sizeof(recordT));
ok = ReadARecord(i, recordT);
if(!ok) break;
// write to file
if(strcmp(recordT.id, id) == 0){
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
::OutputDebugStringW(L"--- ModifyARecord create file fail ---\r\n");
return FALSE;
}
// point to the No.i record
DWORD point = SetFilePointer(hFile, i*sizeof(record), 0, FILE_BEGIN);
// WriteFile
DWORD dwWritenSize = 0;
ok = WriteFile(hFile, &record, sizeof(record), &dwWritenSize, NULL);
if(ok){
// flush the data to file
ok = FlushFileBuffers(hFile);
}
else{
::OutputDebugStringW(L"--- ModifyARecord write a new record to file fail ---\r\n");
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return ok;
}
}
return FALSE;
}
//********************************************************************
// Function : ModifyARecord
// Description : 修改第n条记录
// Input : n : n的取值大于等于0
// Input : record : PhoneRecord结构体
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::ModifyARecord(int n, PhoneRecord record)
{
if(n < 0) return FALSE;
// get file record size
DWORD dwSize;
BOOL ok = GetRecordCount(dwSize);
if(!ok) return FALSE;
if(n >= dwSize) return FALSE;
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
::OutputDebugStringW(L"--- ModifyARecord create file fail ---\r\n");
return FALSE;
}
// point to the No.i record
DWORD point = SetFilePointer(hFile, n*sizeof(record), 0, FILE_BEGIN);
// WriteFile
DWORD dwWritenSize = 0;
ok = WriteFile(hFile, &record, sizeof(record), &dwWritenSize, NULL);
if(ok){
// flush the data to file
ok = FlushFileBuffers(hFile);
}
else{
::OutputDebugStringW(L"--- ModifyARecord write a new record to file fail ---\r\n");
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return TRUE;
}
//********************************************************************
// Function : ReadARecord
// Description : 读取一条记录
// Input : NONE
// Output : record : PhoneRecord结构体
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::ReadARecord(PhoneRecord &record)
{
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
//MessageBox(L"创建test.txt文件失败");
::OutputDebugStringW(L"--- ReadARecord create file fail ---\r\n");
return FALSE;
}
int size = sizeof(record);
memset(&record, 0, size);
DWORD dwReadSize = 0;
// ReadFile
BOOL ok = ReadFile(hFile, &record, size, &dwReadSize, NULL);
CloseHandle(hFile);
return ok;
}
//********************************************************************
// Function : ReadARecord
// Description : 读取第n条记录
// Input : NONE
// Output : record : PhoneRecord结构体
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::ReadARecord(int n, PhoneRecord &record)
{
if(n<0) return FALSE;
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
//MessageBox(L"创建test.txt文件失败");
::OutputDebugStringW(L"--- ReadARecord create file fail ---\r\n");
return FALSE;
}
int size = sizeof(record);
memset(&record, 0, size);
DWORD dwReadSize = 0;
// point to No.n record
DWORD point = SetFilePointer(hFile, n*size, 0, FILE_BEGIN);
/*if(!point){
::OutputDebugStringW(L"--- ReadARecord point to No.n record fail ---\r\n");
return FALSE;
}*/
// ReadFile
BOOL ok = ReadFile(hFile, &record, size, &dwReadSize, NULL);
CloseHandle(hFile);
return ok;
}
//********************************************************************
// Function : CString2Char
// Description : CString转char*
// Input : str : CString类型字符串,可含中英文
// Input : bufInLen : buf的size大小
// Output : buf : char类型字符串
// Output : bufOutLen : 实际读取字符串的长度
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::CString2Char(CString str, char *buf, int bufInLen, int& bufOutLen)
{
if(str.IsEmpty() || buf == NULL || bufInLen<=0) return FALSE;
// CString to WCHAR
WCHAR *wch = (WCHAR*)str.GetBuffer(str.GetLength());
memset(buf, 0, bufInLen);
// WCHRA to char
WideCharToMultiByte( CP_ACP, 0, wch, -1, buf, bufInLen, NULL, NULL );
// get str length, this will cout the string length which can include chinese and english
bufOutLen = 0;
for(int i=0; i<str.GetLength(); i++){
WCHAR data = str.GetAt(i);
if(data > 0x80){
bufOutLen += 2;
}
else{
bufOutLen++;
}
}
return TRUE;
}
//********************************************************************
// Function : Char2CString
// Description : char*转CString
// Input : buf : char类型字符串
// Input : bufLen : buf的长度
// Output : str : CString类型字符串
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::Char2CString(char *buf, int bufLen, CString &str)
{
if(buf == NULL || bufLen<=0) return FALSE;
// char to WCHAR
WCHAR* wch = new WCHAR(bufLen);
memset(wch, 0, sizeof(wch));
MultiByteToWideChar( CP_ACP, 0, buf, bufLen, wch, bufLen/sizeof(WCHAR) );
str = L"";
// WCHAR to CString
for(unsigned int i=0; i<wcslen(wch); i++)
str.AppendChar(wch[i]);
return TRUE;
}
//********************************************************************
// Function : CreateARecord
// Description : 新增一条记录
// Input : record : PhoneRecord结构体
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::GetRecordCount(DWORD &size)
{
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
::OutputDebugStringW(L"--- GetRecordCount create file fail ---\r\n");
size = 0;
return FALSE;
}
// get file size
DWORD dwSize = GetFileSize(hFile, NULL);
CloseHandle(hFile);
size = dwSize/sizeof(PhoneRecord);
return TRUE;
}
//********************************************************************
// Function : FindAEmptyRecord
// Description : 找出最近一条空记录(以phoneNumber为空判断为空记录)
// Input : NONE
// Output : id : n的取值大于等于0
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::FindAEmptyRecord(char* id)
{
if(id == NULL) return FALSE;
BOOL ret = FALSE;
// CreateFile
HANDLE hFile = CreateFile(FILE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE){
//MessageBox(L"创建test.txt文件失败");
::OutputDebugStringW(L"--- ReadARecord create file fail ---\r\n");
return FALSE;
}
// get file size
DWORD dwSize = GetFileSize(hFile, NULL);
if(dwSize <= 0){
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return FALSE;
}
// read a record
PhoneRecord recordT;
DWORD dwReadSize = 0;
for(unsigned int i=0; i<dwSize; i++){
memset(&recordT, 0, sizeof(recordT));
// ReadFile
BOOL ok = ReadFile(hFile, &recordT, sizeof(recordT), &dwReadSize, NULL);
if(!ok) break;
char t_id[4] = "";
char *p = itoa(i, t_id, 10);
if(p == NULL) break;
// query which record has a empty phoneNumber
if(strcmp(recordT.id, t_id) == 0){
if(strlen(recordT.phoneNumber)==0){
memcpy(id, recordT.id, sizeof(recordT.id));
ret = TRUE;
break;
}
}
}
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
return ret;
}
//********************************************************************
// Function : InsertARecord
// Description : 插入一条新记录到文件中(插入到空的record中,无空record则新增一条)
// Input : record : PhoneRecord结构体
// Output : NONE
// return : TRUE/FALSE
//********************************************************************
BOOL CFileHandle::InsertARecord(PhoneRecord record)
{
// find empty record
memset(record.id, 0, sizeof(record.id));
BOOL ok = FindAEmptyRecord(record.id);
if(ok){// do insert
ok = ModifyARecord(record.id, record);
}
else{// do create
// get how many records
DWORD dwSize=0;
ok = GetRecordCount(dwSize);
// char to int
char *p = itoa(dwSize, record.id, 10);
if(p == NULL) return FALSE;
// create a record
ok = CreateARecord(record);
}
return ok;
}