⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filecutmerge.cpp

📁 适合初学者学习以及程序员回顾
💻 CPP
📖 第 1 页 / 共 2 页
字号:

        delete ptempInfo;
 }
 catch(...)
 {
        return false;
 }
        OpenPackage(PkgFileName,false); //重新打开包,重置有关的变量
return true;

}

bool __fastcall FileCutMerge::SavePackageToDisk()
{
        //此函数将文件包写入磁盘文件
        //主要在内部调用

         if(pPackage==NULL)
                return false;
        //创建一个内存流,准备向其中写入文件信息对象
        TMemoryStream *pTemp=new TMemoryStream();
        //向内存流中写入文件个数
        pTemp->Write(&FileNum,sizeof(int));
        //向内存流中写入文件信息对象
        for(int i=0;i<FileNum;i++)
                pTemp->WriteComponent(pVector->at(i));
        //将文件内容附加到文件信息头之后
         pPackage->Seek(0,soFromBeginning);
         pStreamOpt->AppendStream(pTemp,pPackage);
        //清空文件内容
        pPackage->Size=0;
        //再把内存流转换到文件流
        pTemp->Seek(0,soFromBeginning);
        pStreamOpt->AppendStream(pPackage,pTemp);
        //释放内存流
        pTemp->Free();
        //保存文件
        pPackage->Free();
        return true;
}
bool __fastcall FileCutMerge::MergeFile(String MergeFileName)
{
        //此函数将合并分割后多个文件为一完整的文件包
        //MergeFileName是文件名(注意,不包含扩展名)
        //合并完成后,立即重新打开它

        //前提:
        //1.文件分割包系列文件必须完整

        //结果:
        //有错误发生时,返回False
        //合并成功,返回True;
        //并不替换当前包文件

        //注意:
        //合并后的包文件不能有同名文件,因此,有同名文件时要删除
        //但如果是只读文件,则返回错误



        if(FileExists(MergeFileName+".jxl"))
                if(!DeleteFile(MergeFileName+".jxl"))
                        return false;

        TFileStream *pFile=pStreamOpt->OpenFileStream(MergeFileName+".jxl_0","Read");
        if(pFile==NULL)
                return false;
        int num;
        pFile->Read(&num,sizeof(int));
        FileInfo *ptempInfo=new FileInfo(this);
        pFile->ReadComponent(ptempInfo);

        if(ptempInfo->NeedMerge ==false)
        {
                ShowMessage("不是一个分割包!");
                pFile->Free();
                delete ptempInfo;
                return false;
        }


        int totalNum=ptempInfo->MergeTotalNum;
        //关闭文件流
        pFile->Free();
        //创建包文件流
        pFile=pStreamOpt->OpenFileStream(MergeFileName+".jxl","CreateReadWrite");
        if(pFile==NULL)
                return false;
        pFile->Size =0;
        pFile->Seek(0,soFromBeginning);
        //内存流用于保证分割文件不被破坏
        TMemoryStream *pMem=new TMemoryStream();
        //开始逐个读入文件,并合并它们
        for(int i=0;i<totalNum;i++)
        {
                TFileStream *pTemp=pStreamOpt->OpenFileStream(MergeFileName+".jxl_"+IntToStr(i),"ReadWrite");
                if(pTemp==NULL)
                        return false;

                //释放临时文件流对象
                //pTemp->Free();
                pTemp->Read(&num,sizeof(int));
                ptempInfo=new FileInfo(this);
                pTemp->ReadComponent(ptempInfo);
                //记下位置
                int loc=pTemp->Position;
                pTemp->Seek (0,soFromBeginning);
                pMem->Size =0;
                pMem->CopyFrom(pTemp,pTemp->Size);//获取分割文件内容备份
                //截去分割文件信息头
                pMem->Seek (0,soFromBeginning);
                pStreamOpt->CutOutStream(pMem,0,loc);

                //合并文件
                pMem->Seek (0,soFromBeginning);
                pStreamOpt->AppendStream(pFile,pMem);

                pTemp->Free();
                

                delete ptempInfo;
        }

        //合并完成,将其保存入磁盘
        pFile->Free ();
        pMem->Free();
        
        return true;
}

int __fastcall FileCutMerge::GetPackageSize()
{
        //获取当前文件包保存到磁盘后的大小,这是大致估计的
        //因为当用BCB流对象所提供的WirteComponent()写入
        //组件时,会加上其它的一些字节,所以不可能在不写入
        //磁盘之前得知真正的文件大小。
        int totalSize=0;

        for(int i=0;i<FileNum;i++)
        {
                totalSize+=sizeof(*(pVector->at(i)));
        }
        totalSize+=pPackage->Size;
        
        return totalSize;

}

__fastcall FileCutMerge::FileCutMerge(TComponent* Owner)
        :TComponent(Owner)
{
        //缺省构造函数,设置除了文件名之外的所有初始化属性
        //用这个函数创建的对象,应马上用OpenPackage()来
        //打开一个包,或用NewPackage()创建一个包文件
        try
        {
                //创建流操作对象
                pStreamOpt=new FileStreamOpt;
                //创建容器
                pVector=new FileInfos;
                //包流设为0
                pPackage=NULL;
                FileBegin=0;
                FileNum=0;
                PkgFileName="";

        }
        catch(...)
        {

               throw String("类FileCutMerge初始化失败") ;

        }
}

bool __fastcall FileCutMerge::OpenPackage(String PackageFileName,bool NeedCreate)
{
        //此函数打开一个新的包文件,并重新初始化有关的内部数据对象
        try
        {
                //创建流操作对象
                if(pStreamOpt==NULL)
                        pStreamOpt=new FileStreamOpt;
                //创建容器
                if(pVector==NULL)
                        pVector=new FileInfos;

                PkgFileName=PackageFileName;
                FileBegin=0;
                FileNum=0;

                //打开文件包,生成文件包流
                 if(NeedCreate)
                        pPackage=pStreamOpt->OpenFileStream(PackageFileName,"CreateReadWrite");
                 else
                        pPackage=pStreamOpt->OpenFileStream(PackageFileName,"ReadWrite");

                 if(pPackage==NULL)
                        return false;
                //获取文件包中的文件数
                pPackage->Read(&FileNum,sizeof(int));
                //准备取出文件信息包,并将其放入容器中
                int i;
                pVector->clear ();      //先清空原来的容器
                for(i=0;i<FileNum;i++)
                {
                        pInfo=new FileInfo(this);
                        pPackage->ReadComponent(pInfo);
                        pVector->push_back(pInfo);
                }
                //设置文件开始内容位置指针
                FileBegin=pPackage->Position;


                //截去文件信息头
                pStreamOpt->CutOutStream(pPackage,0,FileBegin);
        }
        catch(...)
        {
                return false;
        }
        return true;

}

bool __fastcall FileCutMerge::NewPackage(String PackageFileName)
{
        //创建一个新包,它只是简单地调用OpenPackage,
        //并设NeedCreate为True,提供一个新的文件名
        return OpenPackage(PackageFileName,true);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -