文件读写
2011年06月07日
CFile file; CFileException eErr; CString strFileName = "f:\\txt1.wkb"; LPCTSTR lpszFileName = strFileName; try { if(!file.Open(lpszFileName, CFile::modeReadWrite | CFile::modeCreate, &eErr)) { return ; } CString strbuf = "hello"; file.Write(strbuf,strbuf.GetLength()); strbuf = ""; file.SeekToBegin(); int iFileLen = file.GetLength(); file.Read( strbuf.GetBuffer(iFileLen),iFileLen); strbuf.ReleaseBuffer(); file.Close(); } catch (CFileException* e) { AfxMessageBox("Operating the file failed."); } char * pchTxtFileName="f:\\txt.txt"; HANDLE hFile=::CreateFile(pchTxtFileName,GENERIC_WRITE | GENERIC_READ,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); CString strTmp = "hello"; DWORD dNumOfAccess; ::WriteFile(hFile,strTmp,strTmp.GetLength(),&dNumOfAccess,NUL L); int nLength=::SetFilePointer(hFile,0,NULL,FILE_END); char *pData=new char [nLength+1]; memset(pData,0,nLength+1); ::SetFilePointer(hFile,0,NULL,FILE_BEGIN); ::ReadFile(hFile,pData,nLength,&dNumOfAccess,NULL) ; delete[] pData; CloseHandle(hFile); char *pDt = new char [100]; memset(pDt,'a',3); pDt[3] = '\0'; FILE * pFile=fopen(pchTxtFileName,"wt+"); fprintf(pFile,"%s\r\n",pDt); memset(pDt,0,3); fseek(pFile,0,SEEK_SET); fscanf(pFile,"%s\r\n",pDt); delete [] pDt; fclose(pFile); 大家都知道计算机的存储在物理上是二进制的,所以文本文件与二进制文件的区别并不是物理上的,而是逻辑上的。这两者只是在编码层次上有差异。
简单来说,文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码等等。二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思(这样一个过程,可以看作是自定义编码)。
从上面可以看出文本文件基本上是定长编码的,基于字符嘛,每个字符在具体编码中是固定的,ASCII码是8个比特的编码,UNICODE一般占16个比特。而二进制文件可看成是变长编码的,因为是值编码嘛,多少个比特代表一个值,完全由你决定。大家可能对BMP文件比较熟悉,就拿它举例子吧,其头部是较为固定长度的文件头信息,前2字节用来记录文件为BMP格式,接下来的8个字节用来记录文件长度,再接下来的4字节用来记录bmp文件头的长度。。。大家可以看出来了吧,其编码是基于值的(不定长的,2、4、8字节长的值都有),所以BMP是二进制文件。
二进制文件把内存中的数据按其在内存中存放形式原样输出到磁盘上。
文本文件:把文件看作是一个一个的字符序列。 可用FILE * pFile=fopen(pchTxtFileName,"wt+");中的第二个参数决定读写二进制文件还是文本文件。具体可以查看MSDN。
CFile一般是读写文件文件。 一般常见的是Ansi文本文件,例如上面的三种读写方式的写文件方式。 //写Unicode文本文件,头个字节xfeff,低位xff写在前
CFile file;
file.Open(_T("1.txt"), CFile::modeWrite | CFile::modeCreate);
//文件开头
file.SeekToBegin();
// 决定是Ansi文件还是Unicode文件
file.Write("\xff\xfe", 2); // 没有这一句,则为Ansi文件,这里则表示Unicode文件
//写入内容
file.Write("abc", 3);
file.Flush();
file.Close(); 支持宽字节、多字节环境;支持Ansi、Unicode文本;支持中英文。
最初,直接从网上下了CStdioFileEx类使用,发现好像并不好用。于是自己决定重写。于是花了一天时间,在各种环境下查看微软是如何读文本的。刚开始一直被Unicode文本的读取方式迷惑,知道最后才发现,要用二进制方式读取,否则自动把每一个字节扩展成2个字节。这就是造成乱码的根本原因。查找到原因,就好写了。当然是把CStdioFile的代码copy过来,根据正确环境,用正确的函数。结果发现,网上也是这种方式。虽然解决方法都是一样,但习惯或者思维方式不一样,所以才觉得他的类并不好用。总是觉得,他考虑的有点过于复杂,把简单问题复杂化了。所以按照自己的思路,完完整整的,一字一句的写下了自己的类。
有时,快乐本身,就是一种过程,自己的过程。也许尽管是别人走过的过程,但却属于自己的过程,不一样的过程。
好了,废话不多说。源码如下: 在Windows中我们可以使用注册表或者 ini 文件(Profile)来保存少量数据,如程序的初始化信息,用户设置的数据等。 AfxGetApp()->WriteProfileString(sPath,sKeyPath,m_sP ath); AfxGetApp()->GetProfileString(sFilePath,sKeyFilePat h,""); ini文件(即Initialization file),由若干个节(Section)组成,每个Section由若干键(Key)组成,每个Key可以赋相应的值。读写ini文件实际上就是读写某个的Section中相应的Key的值。 GetPrivateProfileString 读取INI文件指定块中的键名对应的字符串。
GetPrivateProfileInt 读取INI文件指定块中的键名对应的整数值。
GetPrivateProfileStruct 读取INI文件指定块中的键名对应的数据
GetPrivateProfileSection 读取INI文件指定块中的所有键名及其对应值。
GetPrivateProfileSectionNames 读取一INI文件中所有的块名。
GetProfileInt 读取win.ini中指定块中的键名对应的整数值。
GetProfileString 读取win.ini中指定块中的键名的对应值。
GetProfileSection 读取win.ini中指定块中所有的键名及其值。
(win.ini,是Windows系统的一个基本系统配置文件。在C:\Windows下,故用GetProfileInt等函数时,不需要指定路径。但不推荐保存私有消息。)
WritePrivateProfileSection 替换INI文件中指定块中所有键名对应的值。
WritePrivateProfileString 把给定的键名及其值写入到指定INI文件的相应块中。
WritePrivateProfileStruct 把指定的键名及其数据写入到指定INI文件的块中。
WriteProfileSection 替换win.ini中指定块的所有键名对应的值。
WriteProfileString 将给定的键名及值写入win.ini中对应的块中。
例子
// -------------------------------------------------- ------------------------------------------
// [Section1]
// Key1=1
// Key2=2
// Key3=3
//
// [Section2]
// Key4=4
// Key5=5
// Key6=6
// -------------------------------------------------- ------------------------------------------
#define MAX_COUNT 1000
CString iniFile(_T(".\\1.ini"));
// 读取指定块中的键名对应的字符串。
CString val;
GetPrivateProfileString(_T("Section1"), _T("Key1"), _T(""), val.GetBuffer(MAX_COUNT), MAX_COUNT, iniFile);
val.ReleaseBuffer(); // val = "1"
// 读取指定块中的键名对应的整数。
int nVal = GetPrivateProfileInt(_T("Section1"), _T("Key1"), 0, iniFile); // nVal = 1
// 把Key2=2 改成Key2=222
WritePrivateProfileString(_T("Section1"), _T("Key2"), _T("222"), iniFile); 回顾一下WriteProfileString函数的说明
BOOL WriteProfileString(
LPCTSTR lpAppName, // 节的名字,是一个以0结束的字符串
LPCTSTR lpKeyName, // 键的名字,是一个以0结束的字符串。若为NULL,则删除整个节
LPCTSTR lpString // 键的值,是一个以0结束的字符串。若为NULL,则删除对应的键
)
由此可见,要删除某个节,只需要将WriteProfileString第二个参数设为NULL即可。而要删除某个键,则只需要将该函数的第三个参数设为 NULL即可。这是删除系统的win.ini中的节或键,类似的,要删除自己定义的ini文件中的节或键,也可做相同的操作。
如:
::WriteProfileString("Test",NULL,NULL); //删除win.ini中的Test节
::WriteProfileString("Test","id",NULL); //删除win.ini中的id键
::WritePrivateProfileString("Test",NULL,NULL,".\\e x1.ini"); //删除ex1.ini中的Test节
::WritePrivateProfileString("Test","id",NULL,".\\e x1.ini"); //删除ex1.ini中的id键 要判断一个ini文件中有多少个节,最简单的办法就是将所有的节名都找出来,然后统计节名的个数。而要将所有的节名找出来,使用GetPrivateProfileSectionNames函数就可以了,其原型如下:
DWORD GetPrivateProfileSectionNames(
LPTSTR lpszReturnBuffer, // 指向一个缓冲区,用来保存返回的所有节名
DWORD nSize, // 参数lpszReturnBuffer的大小
LPCTSTR lpFileName // 文件名,若该ini文件与程序在同一个目录下,
//也可使用相对路径,否则需要给出绝度路径
)
/* -------------------------------------------------- ----------------------------------------------
Function Name : GetSectionNames
Describe : 读取ini文件中所有的节名
Parameters :
CStringArray& sections ----- [out] 所有节名字符串数组
LPCTSTR lpIniFile ----- [in] ini文件路径
Return type : int ----- 节名个数
-------------------------------------------------- ----------------------------------------------
I D :
Others :
-------------------------------------------------- ----------------------------------------------
Author : Alsmile Date : 2010-8-12
Project :
Version : 1.0.0.1
Module :
-------------------------------------------------- ----------------------------------------------
History :
/* -------------------------------------------------- ------------------------------------------- */
int GetSectionNames(CStringArray& sections, LPCTSTR lpIniFile)
{
const int MaxStringCount = 3000;
int count(0);
try
{
// 所有节名字符串数组
TCHAR szSectionNames[MaxStringCount] = {0};
int length = GetPrivateProfileSectionNames(szSectionNames, MaxStringCount, lpIniFile);
int index(0);
for(int i = 0; i 循环终止
if(szSectionNames[index] == 0)
{
break;
}
}
}
}
catch (...)
{
}
return count;
} /* -------------------------------------------------- ---------------------------------------------- Function Name : GetSectionKeysValues Describe : 读取ini文件中指定节下的所有键名和键值
Parameters :
CStringArray& keys ----- [out] 所有键名字符串数组
CStringArray& vals ----- [out] 所有键值字符串数组
LPCTSTR lpSection ----- [in] 指定节名
LPCTSTR lpIniFile ----- [in] ini文件路径
Return type : int ----- 键个数
-------------------------------------------------- ----------------------------------------------
I D :
Others :
-------------------------------------------------- ----------------------------------------------
Author : Alsmile Date : 2010-8-12
Project :
Version : 1.0.0.1
Module :
-------------------------------------------------- ----------------------------------------------
History :
/* -------------------------------------------------- ------------------------------------------- */
int GetSectionKeysValues(CStringArray& keys, CStringArray& vals, LPCTSTR lpSection, LPCTSTR lpIniFile)
{
const int MaxStringCount = 6000;
int count(0);
TRACE(_T("\n"));
try
{
// 包括key和value的总字符串
TCHAR szKeysVals[MaxStringCount] = {0};
int length = GetPrivateProfileSection(lpSection, szKeysVals, MaxStringCount, lpIniFile);
int index(0);
for(int i = 0; i < length; ++i)
{
if (szKeysVals[i] == '\0')
{
if (i != index)
{
CString lineText(&szKeysVals[index]);
keys.Add(lineText.Left(lineText.Find('=')));
TRACE(keys[count] + _T("="));
vals.Add(lineText.Mid(lineText.Find('=') + 1));
TRACE(vals[count] + _T("\n"));
++count;
}
index = i + 1;
}
}
}
catch (...)
{
}
return count;
}
xml文件读写
推荐使用 tinyXML(使用简单)或 CMarkup
tinyXML:tinyxml使用笔记与总结 (请自己网上google)
CMarkup:CMarkup7.2 概述 CMarkUp函数简介 (请自己网上google这两个文章)
发表评论
-
android之Pull解析XML
2012-01-20 08:49 849android之Pull解析XML 2011年03月03日 ... -
IIS服务器排错指南及错误代码大全
2012-01-20 08:49 1049IIS服务器排错指南及错误代码大全 2011年06月22日 ... -
Delphi 小谈之TList 篇
2012-01-20 08:49 1046Delphi 小谈之TList 篇 2010年08月23日 ... -
D-Bus介绍
2012-01-20 08:49 1528D-Bus介绍 2011年01月19日 ... -
可惜我是水瓶座
2012-01-19 13:54 4345可惜我是水瓶座 2011年1 ... -
失落、失恋时可以听一下的歌。!
2012-01-19 13:54 1243失落、失恋时可以听一 ... -
很喜欢的语言
2012-01-19 13:54 652很喜欢的语言 2011年07月16日 在对的时间,遇见对 ... -
12星座代表的零食
2012-01-19 13:54 66412星座代表的零食 2011年02月13日 便利商店 -
双鱼座
2012-01-19 13:54 801双鱼座 2011年06月18日 ... -
n72手机大瘦身,让你的手机快起来 _n72手机内存清理
2012-01-17 03:43 709n72手机大瘦身,让你的手 ... -
这是我的计算机题目,会做的帮我看下哈。。
2012-01-17 03:43 1714这是我的计算机题目,会做的帮我看下哈。。 2011年12月2 ... -
电脑常见问题主板,CMOS/BIOS,内存常见 故障维修指南 2
2012-01-17 03:43 1132电脑常见问题主板,CMOS/B ... -
计算机基础测试题看看你们能答对多少?
2012-01-17 03:43 1112计算机基础测试题看看你们能答对多少? 2012年01月15日 ... -
如何清除掉“无法删除”的顽固文件
2012-01-17 03:43 1142如何清除掉“无法删除”的顽固文件 2011年08月16日 ... -
小学作文教学中的四个“重视”
2012-01-16 02:20 531小学作文教学中的四个 ... -
小学作文
2012-01-16 02:20 659小学作文 2010年06月02日 ... -
小学语文作文教学浅探
2012-01-16 02:20 749小学语文作文教学浅探 ... -
论小学作文教学生活化
2012-01-16 02:20 594论小学作文教学生活化 2011年03月28日 论小学作文 ... -
谈谈小学作文教学
2012-01-16 02:20 554谈谈小学作文教学 2009 ...
相关推荐
1、 文件读写 包括两个内容:查找文件中“java”字符串的个数;利用命令行参数显示文件的最后指定行。 在查找“java”字符串个数的程序中,先读出文件内容,再逐个字符对比,找出“java”字符,最终把结果写入另一...
excel文件读写excel文件读写excel文件读写
文件读写监控工具文件读写监控工具文件读写监控工具文件读写监控工具文件读写监控工具文件读写监控工具文件读写监控工具
易语言大文件读写模块源码,大文件读写模块,初始化,取总行数,取行文本,条件查询
java文件读写操作大全java文件读写操作大全java文件读写操作大全java文件读写操作大全java文件读写操作大全
qt 内存 映射 大文件读写
C++文件读写操作C++文件读写操作 C++文件读写操作C++文件读写操作
Android - 文件读写操作 方法总结
linux c 配置文件读写 经过测试可以使用 有例子
C#文件读写常用类介绍,System.IO.File类和System.IO.FileInfo类主要提供有关文件的各种操作,在使用时需要引用System.IO命名空间。
java中用FileUtil实现文件读写
MFC INI文件读写;MFC INI文件读写;MFC INI文件读写;MFC INI文件读写;MFC INI文件读写;
易语言使用APIhook进行拦截文件读写,拦截文件读写,使用apihook
配置文件,XML文件读写.rar XML的简单易于在多数应用程序中读/写数据,XML是数据交换的公共语言,很多不同的应用软件都支持XML文件。 配置文件,是一种计算机文件,可以对程序配置初始参数;设置程序初始数据。
操作系统试验之第四文件读写的三种方式比较
读/写属性文件的工具类. PropertyUtil.java对Property文件读写进行了封装, 使开发人员对Property文件的读写更加容易。 在性能、实用性 方面还是可以的。
linux C文件读写 初学练手代码 内容很简单,就实现简单的文件读写功能
C++文件读写流样板
在vs2015下的mfc的csv文件读写操作例程,可以修改对应行列数据
python中的文件读写练习题(csdn)————程序