在vs2010下对一些文件的操作总是有好多疑问
unicade环境下以前的许多资料发现会出现异常结果,下面看看我的问题:
主要是用CFile读取txt出现乱码,我试了好几种方法,最后终于找到了解决方法,但只是方法,还有好多疑问。
目的其实就是读取txt文件,以前用CStdioFile读取的,但是遇到超级大的文件后发现其效率极其低下,就算一个5mb只有一行的txt文件其读取效率也是难以忍受。
以前用CStdioFile读取时也会乱码,但加入了这两段代码之后就没问题了
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" );//设定<ctpye.h>中字符处理方式
……//中间处理
setlocale( LC_CTYPE, old_locale );
free( old_locale );//还原区域设定
虽然可以正常读取,但是大文件就很慢了
于是就改用CFile,在查阅了一些资料后CFile读取txt成功了,但是却读出来的是乱码
后来试了很多方法,最后虽然成功了,但是还是很多问题。
先看看我的几个失败方法:
m_strContent是CString变量;m_strFilePath是文件路径
方法1:
WCHAR *pwBuffer = NULL;
CFile fRead;
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
pwBuffer = new WCHAR[dwLength];
fRead.Read(pwBuffer,dwLength);
m_strContent = pwBuffer;
结果是乱码
方法二:使用CArchive
CFile fRead;
m_strContent=_T("");
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
CArchive ar(&fRead,CArchive::load,dwLength);
ar>>m_strContent;
ar.Close();
fRead.Close();
很神奇的是只读取了一点点,txt里的内容是一串数字,如0.12345 0.3456 1.233 -1.345……这样的数字
它内容是.12345 0.3456 1.233 -1第一个0没了,然后5mb左右的文件就读到了十几个字符。
最后这个方法能正确解决
int nChars;
CFile fRead;
m_strContent=_T("");
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
char *buf=new char[dwLength];
fRead.Read(buf,dwLength);
nChars=MultiByteToWideChar(CP_ACP,0,buf,-1,NULL,0); //获取宽字节所需的缓冲区长度。
TCHAR *wbuff=new TCHAR [nChars];
MultiByteToWideChar(CP_ACP,0,buf,-1,wbuff,nChars);
m_strContent = wbuff;问题1:
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" );//设定<ctpye.h>中字符处理方式
……//中间处理
setlocale( LC_CTYPE, old_locale );
free( old_locale );//还原区域设定
这段代码有什么用呢?问题2:(这是我比较想知道的)
CArchive为何会只读取到那么一点?问题3:
WCHAR和char之间的区别是什么?
unicade环境下以前的许多资料发现会出现异常结果,下面看看我的问题:
主要是用CFile读取txt出现乱码,我试了好几种方法,最后终于找到了解决方法,但只是方法,还有好多疑问。
目的其实就是读取txt文件,以前用CStdioFile读取的,但是遇到超级大的文件后发现其效率极其低下,就算一个5mb只有一行的txt文件其读取效率也是难以忍受。
以前用CStdioFile读取时也会乱码,但加入了这两段代码之后就没问题了
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" );//设定<ctpye.h>中字符处理方式
……//中间处理
setlocale( LC_CTYPE, old_locale );
free( old_locale );//还原区域设定
虽然可以正常读取,但是大文件就很慢了
于是就改用CFile,在查阅了一些资料后CFile读取txt成功了,但是却读出来的是乱码
后来试了很多方法,最后虽然成功了,但是还是很多问题。
先看看我的几个失败方法:
m_strContent是CString变量;m_strFilePath是文件路径
方法1:
WCHAR *pwBuffer = NULL;
CFile fRead;
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
pwBuffer = new WCHAR[dwLength];
fRead.Read(pwBuffer,dwLength);
m_strContent = pwBuffer;
结果是乱码
方法二:使用CArchive
CFile fRead;
m_strContent=_T("");
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
CArchive ar(&fRead,CArchive::load,dwLength);
ar>>m_strContent;
ar.Close();
fRead.Close();
很神奇的是只读取了一点点,txt里的内容是一串数字,如0.12345 0.3456 1.233 -1.345……这样的数字
它内容是.12345 0.3456 1.233 -1第一个0没了,然后5mb左右的文件就读到了十几个字符。
最后这个方法能正确解决
int nChars;
CFile fRead;
m_strContent=_T("");
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
char *buf=new char[dwLength];
fRead.Read(buf,dwLength);
nChars=MultiByteToWideChar(CP_ACP,0,buf,-1,NULL,0); //获取宽字节所需的缓冲区长度。
TCHAR *wbuff=new TCHAR [nChars];
MultiByteToWideChar(CP_ACP,0,buf,-1,wbuff,nChars);
m_strContent = wbuff;问题1:
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" );//设定<ctpye.h>中字符处理方式
……//中间处理
setlocale( LC_CTYPE, old_locale );
free( old_locale );//还原区域设定
这段代码有什么用呢?问题2:(这是我比较想知道的)
CArchive为何会只读取到那么一点?问题3:
WCHAR和char之间的区别是什么?
2.可能对于空格等自动截取了
3.一个是UNICODE字符串,一个是ANSI字符串,两者之间需要编码转换
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" );//设定<ctpye.h>中字符处理方式
WCHAR *pwBuffer = NULL;
CFile fRead;
if (!fRead.Open(m_strFilePath,CFile::modeRead))
{
MessageBox(_T("文件打开出错!"),_T("警告"),MB_ICONERROR);
return;
}
DWORD dwLength = (DWORD)fRead.GetLength();
pwBuffer = new WCHAR[dwLength];
fRead.Read(pwBuffer,dwLength);
m_strContent = pwBuffer;
setlocale( LC_CTYPE, old_locale );
free( old_locale );//还原区域设定我试过是不能的!为啥呢?
char *pBuf;
int iLen=file.GetLength();
pBuf=new char[iLen+1];
file.Read(pBuf,iLen);
pBuf[iLen]=0;
CString str1(pBuf); //CString str1=CA2W(pBuf,CP_UTF8); //Utf8格式文件用此方法
delete[] pBuf;
file.Close();
MessageBox(str1);
txt文件常用的都有4种不同的字符集编码方式,用CString读取内容,不一定是好的办法
pwBuffer = new WCHAR[dwLength/sizeof(WCHAR)];
问题1和3都是编码的问题,慢慢折腾吧。
第二种方法可能是遇到了异常字符什么的,自动就断下来了。