今天的任務是要保存一個文件。平常看別人怎么寫,自己還只是看,沒有動手去寫過,對各個API相應的參數不是很了解。今天在運用的時候,還真是遇見了一些問題。
我們先來說說問題:
第一個問題:使用WriteFile的時候,我直接將寬字符串寫進了文件,文件顯示如大家所想,摻雜了很多亂碼。但是很有規則。所以我很快就明白了這需要將寬字符串轉換成ASCII碼。
第二個問題:就是我將文件打開后,又進行了寫文件的操作,此時失敗。所以對這種情況,還沒有想出辦法,是由于CreateFile的參數的某些限制么?
由于這兩個問題,所以我也好好看了一下SDK文檔。
我們先來看一下CreateFile和WriteFile的原型和參數介紹:
HANDLE CreateFile(
LPCTSTR lpFileName, // 文件名
DWORD dwDesiredAccess, // 訪問方式
DWORD dwShareMode, // 共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 設為NULL
DWORD dwCreationDisposition, /// 創建方式
DWORD dwFlagsAndAttributes, // 屬性
HANDLE hTemplateFile
);
BOOL WriteFile(
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer, // 包含寫向文件的數據
DWORD nNumberOfBytesToWrite, // 數據包含的字符串的個數
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
第一次我寫的程序很簡單
BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer, DWORD dwLen)
{
HANDLE hFile = CreateFile(pFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwSize = 0;
WriteFile(hFile, pBuffer, dwLen, &dwSize, NULL );
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
這樣是完成了,但是寫出來的文件是亂碼。所以沒有進行字符的轉換,我們需要將pBuffer進行轉換。這就要用到了WideCharToMultiByte.如何用呢?
首先我的方法比較笨,我是這么用的:
char* pchBuffer = new char[dwLen+1];
WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen+1, NULL, FALSE );
WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );
Delete[] pchBuffer;
此時注意,我在WriteFile中用了dwLen+1。結果就是在文件的末尾出現了亂碼,正好多一個亂碼出來。所以WriteFile中nNumberOfBytesToWrite是寫的字符串的數目,是不包括’\0’的。
這個方法笨,是因為我們的函數可以縮減為兩個參數。是因為如下這么寫時,dwLen是所要轉換的字符串的個數,此時轉換的字符串是包括’\0’的。
DWORD dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL, NULL, FALSE );
所以我們再來看一下改寫以后的代碼
BOOL WriteOwnFile(TCHAR* pFileName, TCHAR* pBuffer)
{
HANDLE hFile = CreateFile(pFileName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD dwSize = 0;
DWORD dwLen = WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, NULL, NULL, NULL, FALSE );
char* pchBuffer = new char[dwLen];
WideCharToMultiByte(CP_ACP, NULL, pBuffer, -1, pchBuffer, dwLen, NULL, FALSE );
WriteFile(hFile, pBuffer, dwLen+1, &dwSize, NULL );
delete[] pchBuffer;
CloseHandle(hFile);
return TRUE;
}
return FALSE;
}
這樣感覺代碼好看多了。
對于第二個問題,文件打開的時候文件創建失敗,還沒有想好辦法解決。我在想是不是我的某些認知存在問題,文件打開的時候,是否可以用CreateFile來打開呢?
posted on 2009-02-09 22:14
Sandy 閱讀(52777)
評論(13) 編輯 收藏 引用 所屬分類:
windows學習