您的位置:首页 > 其它

文件操作:CreateFile和WriteFile的学习

2009-12-28 17:06 344 查看
今天的任务是要保存一个文件。平常看别人怎么写,自己还只是看,没有动手去写过,对各个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息