保存和读取文件

保存和读取文件

更新日期:2011-1-22
示例代码:demo.zip (请不要使用下载工具,否则可能出错)

测试环境:VC6.0+WinXP

━━━━━━━━━━━━━━━━━━━━━━━━

一、CMyFile实现了序列化保存和读取文件。你可以使用它保存和读取常用数据类型,如
    1. int double short 等固定大小的变量,
    2. 字符串变量,c风格字符串,stl 字符串string,MFC字符串CString
    3. 保存stl的vector<T> 类型的变量
    4. 保存结构体或结构体数组
    5. 支持UNICODE

二、调用示例:


struct TEST
{
    int a;
    int b;
};

/****************************************************************************
保存数据
****************************************************************************/
bool write()
{
    trace(_T("*****保存数据*****************"));

    //1.vector 变量
    vector <TEST> button;
    for (int i=0;i<4;i++)
    {
        TEST temp={i,i+10};
        button.push_back(temp);
    }

    //2.普通变量和结构体
    TEST a={88,99};
    int aa=34;
    double bb=11.352;

    //3.字符串变量
    TCHAR c_str[100]=_T("this is a c style string");
    __string stlstr=_T("this is a stl string");
    CString mfcstr=_T("this is a mfc CString");

    //4.保存用new创建的字符串
    TCHAR* newstr;
    newstr=new TCHAR[100];
    _tcsncpy(newstr,_T("the string using new"),99);

    //5.定义一个结构体指针,就一定要有相应的保存数量的变量count
    int count=10;
    TEST* pp=new TEST[count];
    for (int i=0;i<count;i++)
    {
        pp[i].a=i;
        pp[i].b=i+100;
    }

    try
    {
        CMyFile file(_T("s.txt"),_T("wb"));

        file.WriteVector(button);
        file.WriteString(c_str);
        file.WriteString(stlstr);
        file.WriteString(mfcstr);
        file.WriteStruct(a);
        file.WriteStruct(aa);
        file.WriteStruct(bb);
       
        file.WriteString(newstr);
        delete[] newstr;
        newstr=NULL;

        file.WriteNewStruct(pp,count);
        delete[] pp;
        pp=NULL;

        trace(_T("CMyFile Write Successful"));
        return true;
    }
    catch(int ErrorCode)
    {
        trace(_T("CMyFile Write Failed"),ErrorCode);
        return false;
    }
}


/****************************************************************************
读取数据
****************************************************************************/
bool read()
{
    trace(_T("*****读取数据*****************"));

    //1.vector 变量
    vector <TEST> button;

    //2.普通变量和结构体
    int aa=0;
    double bb=0;
    TEST a;

    //3.字符串变量
    TCHAR c_str[100]={0};
    __string stlstr;
    CString mfcstr;

    //4.保存用new创建的字符串
    TCHAR* newstr;

    //5.定义一个结构体指针,就一定要有相应的保存数量的变量count
    TEST* pp;
    int count;

    try
    {
        CMyFile file(_T("s.txt"),_T("rb"));

        file.ReadVector(button);
        file.ReadString(c_str,sizeof(c_str)/sizeof(TCHAR));
        file.ReadString(stlstr);
        file.ReadString(mfcstr);
        file.ReadStruct(a);
        file.ReadStruct(aa);
        file.ReadStruct(bb);

        for (UINT i=0;i<button.size();i++)
            trace(button[i].a,button[i].b);
       
        trace(c_str);
        trace(stlstr);
        trace(mfcstr);
        trace(a.a,a.b);
        trace(aa,bb);
   

        //读取用new创建的字符串
        newstr=file.ReadNewString();
        trace(newstr);
        delete[] newstr;
        newstr=NULL;

        count=file.ReadNewStruct(pp);
        trace(count);
        for (int i=0;i<count;i++)
            trace(pp[i].a,pp[i].b);
        delete[] pp;   
        pp=NULL;

        trace(_T("CMyFile Read Successful"));
        return true;
    }
    catch(int ErrorCode)
    {
        trace(_T("CMyFile Read Failed"),ErrorCode);
        return false;
    }
}


void CDemoDlg::OnButton1()
{
    write();
}


void CDemoDlg::OnButton2()
{
    read();
}



三、CMyFile源代码(MyFile.h)

/****************************************************************************
读取和保存文件

一、CMyFile实现了序列化保存和读取文件。你可以使用它保存和读取常用数据类型,如
    1. int double short 等固定大小的变量,
    2. 字符串变量,c风格字符串,stl 字符串string,MFC字符串CString
    3. 保存stl的vector<T> 类型的变量
    4. 保存结构体或结构体数组
    5. 支持UNICODE

二、更新日期:2011-1-22
    请浏览一下网址看是否有所更新:
    http://blog.csdn.net/jacky_qiu/archive/2010/12/24/6096722.aspx

三、调用示例:
    通常你需要写两个函数write()和read()用于读取和保存。
    里面还需要用try和catch来捕获保存和读取时可能出现的异常。
    格式如下:

    //保存
    bool write2()
    {
        int a=89;
        TCHAR c_str[100]=_T("this is a c style string");

        try
        {
            CMyFile file(_T("s.txt"),_T("wb"));
            file.WriteStruct(a);
            file.WriteString(c_str);
            return true;
        }
        catch(int ErrorCode)
        {
            return false;
        }
    }

    //读取
    bool read2()
    {
        int a;
        TCHAR c_str[100]={0};

        try
        {
            CMyFile file(_T("s.txt"),_T("rb"));
            file.ReadStruct(a);
            file.ReadString(c_str,sizeof(c_str)/sizeof(TCHAR));
            return true;
        }
        catch(int ErrorCode)
        {
            return false;
        }
    }

****************************************************************************/

#ifndef _MY_FILE_H_
#define _MY_FILE_H_

#include <vector>
#include <string>

//兼容ANSI和UNICODE
#ifdef    _UNICODE   
#define __fopen            _wfopen
#define __string        wstring   
#else   
#define __fopen            fopen
#define __string        string
#endif   
   
class CMyFile
{
public:
    FILE* fp;

    CMyFile(const TCHAR* filename, const TCHAR* mode )
    {
        fp=__fopen(filename,mode);   
        if (fp==NULL)    throw int(0);
    }

    ~CMyFile()    {    fclose(fp);    }

    /****************************************************************************
    重新定位到文件开头
    ****************************************************************************/
    void fpReset() {rewind(fp);}


    /****************************************************************************
    保存vector
    ****************************************************************************/
    template <class T> void WriteVector(std::vector<T>& vec)
    {
        UINT count=vec.size();           
       
        //保存个数
        if (1!=fwrite(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(1);
        }

        if (count==0)
            return;

        //保存vector的所有元素
        if (count!=fwrite(&vec[0],sizeof(T),count,fp))        
        {
            fclose(fp);
            throw int(2);
        }
    }

    /****************************************************************************
    读取vector
    ****************************************************************************/
    template <class T> void ReadVector(std::vector<T>& vec)
    {
        UINT count=0;    //一定要是UINT,否知有可能会出现负数

        //读取个数
        if (1!=fread(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(3);
        }

        //最多读取10万个数据
        if (count>100000)       
        {
            fclose(fp);
            throw int(4);
        }

        //设置Data的长度
        vec.resize(count);   

        if (count==0)
            return;

        if ( count!=fread(&vec[0],sizeof(T),count,fp) )
        {
            fclose(fp);
            throw int(5);
        }
    }
   
    /****************************************************************************
    保存结构体,包括int double 之类的固定大小的变量
    ****************************************************************************/
    template <class T> void WriteStruct(T& Data)
    {
        if (1!=fwrite(&Data,sizeof(T),1,fp))
        {
            fclose(fp);
            throw int(6);
        }
    }
   
    /****************************************************************************
    读取结构体,包括int double 之类的固定大小的变量
    ****************************************************************************/
    template <class T> void ReadStruct(T& Data)
    {
        if( 1!=fread(&Data,sizeof(T),1,fp))
        {
            fclose(fp);
            throw int(7);
        }
    }
   

    /****************************************************************************
    保存string字符串
    ****************************************************************************/
    void WriteString(std::__string& str)
    {
        UINT count=str.size();   

        //保存个数
        if (1!=fwrite(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(8);
        }

        if (count!=fwrite(str.c_str(),sizeof(TCHAR),count,fp))    
        {
            fclose(fp);
            throw int(9);
        }
    }

    /****************************************************************************
    读取字符串并放在一个string里
    ****************************************************************************/
    void ReadString(std::__string& str)
    {
        UINT count=0;
       
        //读取个数
        if (1!=fread(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(10);
        }

        TCHAR* NewStr=new TCHAR[count+1];

        if (count!=fread(NewStr,sizeof(TCHAR),count,fp))
        {
            delete[] NewStr;
            throw int(11);
        }

        NewStr[count]=NULL;

        str=NewStr;
        delete[] NewStr;
    }

#ifdef __AFXWIN_H__
    /****************************************************************************
    保存CString字符串
    ****************************************************************************/
    void WriteString(CString& str)
    {
        UINT count=str.GetLength();       

        //保存个数
        if (1!=fwrite(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(12);
        }

        if (count!=fwrite(str,sizeof(TCHAR),count,fp))    
        {
            fclose(fp);
            throw int(13);
        }
    }

    /****************************************************************************
    读取字符串并放在一个CString里
    ****************************************************************************/
    void ReadString(CString& str)
    {
        UINT count=0;
       
        //读取个数
        if (1!=fread(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(14);
        }

        TCHAR* NewStr=new TCHAR[count+1];

        if (count!=fread(NewStr,sizeof(TCHAR),count,fp))
        {
            delete[] NewStr;
            throw int(15);
        }

        NewStr[count]=NULL;

        str=NewStr;
        delete[] NewStr;
    }
#endif


    /****************************************************************************
    保存字符串
    ****************************************************************************/
    void WriteString(TCHAR* str)
    {
        UINT count=_tcslen(str);       

        //保存个数
        if (1!=fwrite(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(16);
        }

        if (count!=fwrite(str,sizeof(TCHAR),count,fp))    
        {
            fclose(fp);
            throw int(17);
        }
    }

    /****************************************************************************
    读取字符串
    max包括了空字符,所以str的最大字符数为max-1
    ****************************************************************************/
    UINT ReadString(TCHAR* str,unsigned int max)
    {
        UINT count=0;

        //读取个数
        if (1!=fread(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(18);
        }

        if (count>max-1)       
        {
            fclose(fp);
            throw int(19);
        }

        if( count!=fread(str,sizeof(TCHAR),count,fp))   
        {
            fclose(fp);
            throw int(20);
        }
        str[count]=NULL;
        return count;
    }
       
    /****************************************************************************
    读取字符串(使用完后需手动删除,delete[] str)
    当读取的是一个空字符串(WriteString时只写了一个count=0进入文件),
    则ReadNewString会new一个字符NULL,所以我们可以安全引用此字符串指针。
    ****************************************************************************/
    TCHAR* ReadNewString()
    {
        UINT count=0;

        //读取个数
        if (1!=fread(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(21);
        }

        if (count>100000)       
        {
            fclose(fp);
            throw int(22);
        }
       
        TCHAR* str=new TCHAR[count+1];
       
        if( count!=fread(str,sizeof(TCHAR),count,fp))   
        {
            delete[] str;
            fclose(fp);
            throw int(23);
        }
       
        str[count]=NULL;//length=100时,PasteText[length]就是第101个字符,也就是最后一个NULL
       
        return str;
    }
   
   
    /****************************************************************************
    保存结构体数组
    即使pStruct为NULL,也可以调用此函数   
    ****************************************************************************/
    template <class T> void WriteNewStruct(T* pStruct,UINT count)
    {
        //保存个数
        if (1!=fwrite(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(24);
        }
       
        if (count!=fwrite(pStruct,sizeof(T),count,fp))    
        {
            fclose(fp);
            throw int(25);
        }
    }
   
    /****************************************************************************
    读取结构体数组
    每次调用ReadNewStruct获得的结构体数组,在使用前必须判断是否为空
    使用完需要delete[] pStruct
    ****************************************************************************/
    template <class T> int ReadNewStruct(T* &pStruct)
    {
        UINT count=0;

        //读取个数
        if (1!=fread(&count,sizeof(count),1,fp))
        {
            fclose(fp);
            throw int(26);
        }

        if (count>100000)       
        {
            fclose(fp);
            throw int(27);
        }
       
        if (count==0)
        {
            pStruct=NULL;
            return 0;
        }
       
        pStruct=new T[count];
       
        if( count!=fread(pStruct,sizeof(T),count,fp))   
        {
            delete[] pStruct;
            fclose(fp);
            throw int(28);
        }
       
        return count;
    }


};


#endif    // #define _MY_FILE_H_
 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值