20.c++-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);// 设回原来的当前值
<span style="white-space:pre">	</span>fclose(fp);
	return size;
}

取得文件大小

 小例子:

//********************************************
//	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;
		}
	}
}


 



 

你可能感兴趣的:(File,null,FP)