FILE详解
DWORD MyGetFileSize(const char* FileName)
{
FILE *fp = fopen(FileName, "rb");
if (NULL == fp)
{
return 0;
}
DWORD pos = ftell(fp);// 返回当前值,pos保存当前值
fseek(fp, 0, SEEK_END);// 定位到最后
DWORD size = ftell(fp); // 返回当前值,为文件大小size
fseek(fp, pos, SEEK_SET);// 设回原来的当前值
fclose(fp);
return size;
}
取得文件大小
下面贴个网上当来的FILE读写小例子:
//******************************************** // Ini 相关函数 //******************************************** #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdisp.h> // MFC Automation classes #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #include <afxcmn.h> #ifndef _INI_H_ #define _INI_H_ #ifndef SAFE_DELETE #define SAFE_DELETE(x) if( (x)!=NULL ) { delete (x); (x)=NULL; } #endif #ifndef SAFE_DELETE_ARRAY #define SAFE_DELETE_ARRAY(x) if( (x)!=NULL ) { delete[] (x); (x)=NULL; } #endif #ifndef SAFE_FREE #define SAFE_FREE(x) if( (x)!=NULL ) { free(x); (x)=NULL; } #endif #ifndef SAFE_RELEASE #define SAFE_RELEASE(x) if( (x)!=NULL ) { (x)->Release(); (x)=NULL; } #endif #define ERROR_DATA -99999999 //配置文件类 class CIni { public: bool Open(char *); // 打开配置文件 void Close(); // 关闭配置文件 void Save(char *filename=NULL); // 保存配置文件 int ReadInt(char *, char *); // 读一个整数 char *ReadText(char *, char *); // 读一个字符串 void Write(char *, char *, int); // 写一个整数 void Write(char *, char *, char *); // 写一个字符串 void DeleteIndex(char *index); // 删除一段 void DeleteName(char *index,char *name); // 删除段中一键名行 void AddIndex(char *); //加入一个索引 int FindHead(int index, char *string); int FindIndex(char *); // 返回标题位置 CIni(); CIni(char*); //初始化打开配置文件 virtual ~CIni(); //释放内存 private: void InitIndex(); // 初始化索引 int FindData(int, char *); // 返回数据位置 int GotoNextLine(int); // 获得下一行 char *ReadDataName(int &); // 在指定位置读一数据名称 char *ReadText(int); // 在指定位置读字符串 char *ReadHeadName(int &p); void AddData(int, char *, char *); //在当前位置加入一个数据 void ModityData(int, char *, char *); //在当前位置修改一个数据的值 int GotoLastLine(char *index); //把指针移动到本INDEX的最后一行 char m_strFileName[MAX_PATH]; //文件名 long m_lDataLen; //文件长度 char *m_strData; //文件内容 int IndexNum; //索引数目([]的数目) int *IndexList; //索引点位置列表 int Point; //当前指针 int Line, Word; //当前行列 }; #endif
.cpp
// Ini 相关函数 //------------------------------------------------------------------ // 包含 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <io.h> #include <fcntl.h> #include <assert.h> #include "ini.h" //------------------------------------------------------------------- // 对外接口 //------------------------------------------------------------------- //------------------------------------------------------------------------------------- // 初始化/析构释放 //------------------------------------------------------------------------------------- CIni::CIni() { m_lDataLen = 0; m_strData = NULL; IndexNum = 0; IndexList = NULL; } CIni::CIni(char *filename) { m_lDataLen = 0; m_strData = NULL; IndexNum = 0; IndexList = NULL; Open(filename); } CIni::~CIni() { if( m_lDataLen != 0 ) { SAFE_DELETE( m_strData ); m_lDataLen = 0; } if( IndexNum != 0 ) { SAFE_DELETE( IndexList ); IndexNum = 0; } } //------------------------------------------------------------------------------------- // 功能:读入配置 // 入口:文件全路径;出口:无 //------------------------------------------------------------------------------------- bool CIni::Open(char *filename) { strcpy(m_strFileName, filename); SAFE_FREE( m_strData ); int fh; fh = _open( filename, _O_RDONLY ); // 只读方式 if( fh== -1 ) m_lDataLen = -1; m_lDataLen = _filelength(fh); // 获取文件长度 _close(fh); if( m_lDataLen > 0 )// 文件存在 { m_strData = new char[m_lDataLen];// 申请空间 FILE *fp; fp=fopen(filename, "rb"); fread(m_strData, m_lDataLen, 1, fp);// 读数据 fclose(fp); InitIndex(); // 初始化索引 return true; } else // 文件不存在 { m_lDataLen=1; m_strData = new char[m_lDataLen]; memset(m_strData, 0, 1); InitIndex(); } return false; } //------------------------------------------------------------------------------------- // 功能:释放内存 // 入口:无;出口:无 //------------------------------------------------------------------------------------- void CIni::Close() { if( m_lDataLen != 0 ) { SAFE_DELETE( m_strData ); m_lDataLen = 0; } if( IndexNum != 0 ) { SAFE_DELETE( IndexList ); IndexNum = 0; } } //------------------------------------------------------------------------------------- // 功能:写入文件 // 入口:文件全路径;出口:无 //------------------------------------------------------------------------------------- void CIni::Save(char *filename) { if( filename==NULL ) filename=m_strFileName; FILE *fp; fp=fopen(filename, "wb"); fwrite(m_strData, m_lDataLen, 1, fp); fclose(fp); } //------------------------------------------------------------------------------------- // 功能:读一字符串数据 // 入口:段名,键名;出口:字符数据 //------------------------------------------------------------------------------------- char *CIni::ReadText(char *index, char *name) { int n=FindIndex(index); // 找索引 int m=FindData(n, name); // 找键名 return ReadText(m); // 获得键值 } //------------------------------------------------------------------------------------- // 功能:读一整数 // 入口:段名,键名;出口:整数 //------------------------------------------------------------------------------------- int CIni::ReadInt(char *index, char *name) { int n=FindIndex(index); // 找索引 int m=FindData(n, name); // 找键名 char *str=ReadText(m); // 获得键值 int ret=atoi(str); // 字符转化为整数 free(str); return ret; } //------------------------------------------------------------------------------------- // 功能:写一字符串数据 // 入口:段名,键名,键值;出口:无 //------------------------------------------------------------------------------------- void CIni::Write(char *index, char *name, char *string) { int n=FindIndex(index); if( n == -1 ) // index不存在,新建一个索引 { AddIndex(index); // 添加索引 n=FindIndex(index); // 找到索引位置 n=GotoLastLine(index); // 取得它的下一行 AddData(n, name, string); //在当前位置n加一个数据 return ; } int m=FindData(n, name);// index索引存在 if( m==-1 ) // 索引存在,键名不存在,新建数据 { n=GotoLastLine(index); AddData(n, name, string); // 在当前位置n加一个数据 return ; } // 键名存在 ModityData(n, name, string); // 修改一个数据 return; } //------------------------------------------------------------------------------------- // 功能:写一整数 // 入口:段名,键名,键值;出口:无 //------------------------------------------------------------------------------------- void CIni::Write(char *index, char *name, int num) { char string[32]; sprintf(string, "%d", num); int n=FindIndex(index); if( n == -1 ) // 新建索引 { AddIndex(index); // 添加一个索引 n=FindIndex(index); n=GotoLastLine(index); // 获得本段最后一行 AddData(n, name, string); // 在当前位置n加一个数据 return; } int m=FindData(n, name); // 存在索引,找到键名首位置 if( m==-1 ) // 键名不存在,新建数据 { n=GotoLastLine(index); AddData(n, name, string); //在当前位置n加一个数据 return; } // 存在数据 ModityData(n, name, string); //修改一个数据 return; } //------------------------------------------------------------------------------------- // 功能:删除一段 // 入口:段名;出口:无 //------------------------------------------------------------------------------------- void CIni::DeleteIndex(char *index) { // char *name; int n = FindIndex(index); // 找索引 if( n == -1 ) return; // 没有此段返回 n = GotoNextLine(n); // 获得首键名地址 // name = ReadHeadName(n); // 获得=之前的数据 // Write(index, name, 0); // n = GotoNextLine(n); int next = GotoLastLine(index); // 获得本段最后一行 if( m_strData[next] == EOF ) { m_lDataLen = n; // 更新长度 m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存 InitIndex(); // 更新索引 return; } char *temp=new char[m_lDataLen-next]; memcpy(temp, &m_strData[next], m_lDataLen-next); // 把next至最后的这一段长度内容保存 memcpy(&m_strData[n], temp, m_lDataLen-next); // 把next至最后的这一段长度内容向前移 m_lDataLen -= next-n; // 更新长度 m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存 InitIndex(); // 更新索引 } //------------------------------------------------------------------------------------- // 功能:删除一行 // 入口:段名;出口:无 //------------------------------------------------------------------------------------- void CIni::DeleteName(char *index,char *name) { int m; int n = FindIndex(index); // 找索引 if( n == -1 ) return; // 没有此段返回 n = FindHead(n, name); // 找键名 if( n == -1 ) // 键名不存在返回 return; m = GotoNextLine(n); // 获得下一行的起始位置 char *temp=new char[m_lDataLen-m]; memcpy(temp, &m_strData[m], m_lDataLen-m); // 把m至最后的这一段长度内容保存 memcpy(&m_strData[n], temp, m_lDataLen-m); // 把m至最后的这一段长度内容向前移 m_lDataLen -= m-n; // 更新长度 m_strData = (char *)realloc(m_strData, m_lDataLen); // 重新分配内存 InitIndex(); // 更新索引 } //-------------------------------------------------------------------------- // 内部函数 //-------------------------------------------------------------------------- //------------------------------------------------------------------------------------- // 功能:计算出所有的索引位置 // 入口:无;出口:无 //------------------------------------------------------------------------------------- void CIni::InitIndex() { IndexNum=0; for(int i=0; i<m_lDataLen; i++) { if( m_strData[i]=='[' && ( m_strData[i-1]=='\n' || i==0 ) )// 找到一个 IndexNum++; } SAFE_DELETE( IndexList ); if( IndexNum>0 ) IndexList=new int[IndexNum];// 申请内存 int n=0; for(i=0; i<m_lDataLen; i++) { if( m_strData[i]=='[' && ( m_strData[i-1]=='\n' || i==0 ) ) { IndexList[n]=i+1; // 记录位置 n++; } } } //------------------------------------------------------------------------------------- // 功能:返回指定段名位置 // 入口:指定段名;出口:首位置 //------------------------------------------------------------------------------------- int CIni::FindIndex(char *string) { for(int i=0; i<IndexNum; i++) { char *str=ReadText( IndexList[i] ); if( strcmp(string, str) == 0 ) { SAFE_FREE( str ); return IndexList[i]; } SAFE_FREE( str ); } return -1; } //------------------------------------------------------------------------------------- // 功能:返回指定数据的位置 // 入口:索引,指定键名;出口:键名首位置 //------------------------------------------------------------------------------------- int CIni::FindHead(int index, char *string) { int p=index; // 指针 char *name; while(1) { p = GotoNextLine(p); // 获得下一行起始位置 name = ReadHeadName(p); // 获得=之前的数据 if( strcmp(string, name)==0 ) { SAFE_FREE( name ); return p; } SAFE_FREE( name ); if( p>=m_lDataLen || m_strData[p] == '[' ) return -1; } return -1; } //------------------------------------------------------------------------------------- // 功能:返回指定数据的位置 // 入口:索引,指定键名;出口:键名=号的位置 //------------------------------------------------------------------------------------- int CIni::FindData(int index, char *string) { int p=index; // 指针 char *name; while(1) { p = GotoNextLine(p); // 获得下一行起始位置 if( p>=m_lDataLen || m_strData[p] == '[' ) return -1; name = ReadDataName(p); // 获得=之前的数据 if( strcmp(string, name)==0 ) { SAFE_FREE( name ); return p; } SAFE_FREE( name ); } return -1; } //------------------------------------------------------------------------------------- // 功能:获得下一行起始位置 // 入口:位置;出口:下一行首位置 //------------------------------------------------------------------------------------- int CIni::GotoNextLine(int p) { for(int i=p; i<m_lDataLen; i++) { if( m_strData[i]=='\n' ) return i+1; } return i; } //------------------------------------------------------------------------------------- // 功能:在指定位置读一数据名称 // 入口:行首位置;出口:=号后的字符串 //------------------------------------------------------------------------------------- char *CIni::ReadDataName(int &p) { char chr; char *Ret; int m=0; Ret=new char[MAX_PATH]; memset(Ret, 0, MAX_PATH); for(int i=p; i<m_lDataLen; i++) { chr = m_strData[i]; if( chr == '\r' || chr == '=' || chr == ';' )// 结束 { p=i+1; return Ret; } Ret[m]=chr; m++; } return Ret; } //------------------------------------------------------------------------------------- // 功能:在指定位置读一数据名称 // 入口:行首位置;出口:=号后的字符串 //------------------------------------------------------------------------------------- char *CIni::ReadHeadName(int &p) { char chr; char *Ret; int m=0; Ret=new char[MAX_PATH]; memset(Ret, 0, MAX_PATH); for(int i=p; i<m_lDataLen; i++) { chr = m_strData[i]; if( chr == '\r' || chr == '=' || chr == ';' )// 结束 { return Ret; } Ret[m]=chr; m++; } return Ret; } //------------------------------------------------------------------------------------- // 功能:在指定位置读一字符串,p为索引位置 // 入口:行首位置;出口:=号前的字符串 //------------------------------------------------------------------------------------- char *CIni::ReadText(int p) { char chr; char *Ret; int n=p, m=0; int LineNum = GotoNextLine(p) - p + 1; Ret=new char[LineNum]; memset(Ret, 0, LineNum); for(int i=0; i<m_lDataLen-p; i++) { chr = m_strData[n]; if( chr == ';' || chr == '\r' || chr == '\t' || chr == ']' )// 结束 { return Ret; } Ret[m]=chr; m++; n++; } return Ret; } //------------------------------------------------------------------------------------- // 功能:加入一个索引 // 入口:索引;出口:无 //------------------------------------------------------------------------------------- void CIni::AddIndex(char *index) { char str[MAX_PATH]; memset(str, 0, MAX_PATH); sprintf(str,"\r\n[%s]\r\n",index); m_strData = (char *)realloc(m_strData, m_lDataLen+strlen(str)); // 重新分配内存 sprintf(&m_strData[m_lDataLen], "%s", str); // 写入索引 m_lDataLen+=strlen(str); // 长度指向最后 InitIndex(); // 重建索引 } //------------------------------------------------------------------------------------- // 功能:在当前位置加入一个数据 // 入口:当前行的首点,键名,键值;出口:无 //------------------------------------------------------------------------------------- void CIni::AddData(int p, char *name, char *string) { char *str; int len; str=new char[2*MAX_PATH]; memset(str, 0, 2*MAX_PATH); sprintf(str,"%s=%s\r\n",name,string); len=strlen(str); m_strData = (char *)realloc(m_strData, m_lDataLen+len); // 重新分配内存 char *temp=new char[m_lDataLen-p]; memcpy(temp, &m_strData[p], m_lDataLen-p); // 把p至最后的这一段长度内容保存 memcpy(&m_strData[p+len], temp, m_lDataLen-p); // 把p至最后的这一段长度内容向后移 memcpy(&m_strData[p], str, len); // 在p存入字符串 m_lDataLen+=len; // 长度增加 SAFE_DELETE(temp); SAFE_DELETE(str); InitIndex(); // 更新索引 } //------------------------------------------------------------------------------------- // 功能:在当前位置修改一个数据的值 // 入口:当前行的首点,键名,键值;出口:无 //------------------------------------------------------------------------------------- void CIni::ModityData(int p, char *name, char *string) { int n=FindData(p, name); char *t=ReadText(n); p=n+strlen(t); // p指向本行最后,n指向=号后 if( strlen(t)>0 ) free(t); int newlen=strlen(string); int oldlen=p-n; m_strData = (char *)realloc(m_strData, m_lDataLen+newlen-oldlen); // 重新分配内存 char *temp=new char[m_lDataLen-p]; memcpy(temp, &m_strData[p], m_lDataLen-p); // 把p至最后的这一段长度内容保存 memcpy(&m_strData[n+newlen], temp, m_lDataLen-p); // 把p至最后的这一段长度内容向后移 memcpy(&m_strData[n], string, newlen); // 在n存入新字符串 m_lDataLen+=newlen-oldlen; // 更新长度 SAFE_DELETE( temp ); InitIndex(); // 更新索引 } //------------------------------------------------------------------------------------- // 功能:把指针移动到本INDEX的最后一行 // 入口:索引点;出口:段内最后一行首位置 //------------------------------------------------------------------------------------- int CIni::GotoLastLine(char *index) { int n=FindIndex(index); n=GotoNextLine(n); while(1) { if( m_strData[n] == '\r' || m_strData[n] == EOF || m_strData[n] == -3 || m_strData[n] == ' ' || m_strData[n] == '/' || m_strData[n] == '\t' || m_strData[n] == '\n' ) { return n; } else { n=GotoNextLine(n); if( n >= m_lDataLen ) return n; } } }