文件分割与合并代码实现

来源:互联网 发布:海贼王pop淘宝 编辑:程序博客网 时间:2024/05/06 09:53

source:

//All right revsered by yoki2009
//mailto:imj040144@tom.com
//微出版 www.epube.biz 相信梦想无界

#include <cctype>
#include <cstddef>
#include <cstdlib>
#include <cstdio>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <map>
#include "DefException.h"

using namespace std;

#define BUF_SIZ  8096

namespace FILESPLIT
{
 static int cnt = 0;
 
 int initConfig()
 {
  WritePrivateProfileString("Config","ID",
   "0","./docid.pos");
  return TRUE;
 }
 
 map<int , string> filelist;
 static int fileid = 1;

 int splitGreatToSlice(const string &srcName)
 {
  filelist[fileid] = srcName;
  fileid++;
  ifstream infile(srcName.c_str(),ios_base::binary);
  if (!infile)
  {
   throw err::RunException("Open File Error.");
   return FALSE;
  }
  bool isEnd = FALSE;
  //check if it is the first time to splite the file
  char recordID[16];

  GetPrivateProfileString("Config","ID","0",recordID,16,"./docid.pos");
  char bstartFile[64];
  char bendpos[4];

  if (!strcmp(recordID,"0"))
  {
   cnt = 0;
  }else
  {
   cnt = atoi(recordID);

   GetPrivateProfileString("Config","LastFile","",
    bstartFile,64,"./docid.pos");
   GetPrivateProfileString("Config","LastFilePos","0",
    bendpos,4,"./docid.pos"); 
  }

  ostringstream oss;
  oss<<"tmp."<<cnt;

  WritePrivateProfileString(srcName.c_str(),"StartFile",
   oss.str().c_str(),"./docid.pos");
  while(!isEnd)
  {
   oss.str("");
   oss<<"tmp."<<cnt;
   cnt++;

   ofstream outfile(oss.str().c_str(),ios_base::binary|ios_base::app);
   if (!outfile)
   {
    throw err::RunException("Create tmp File Error.");
    return FALSE;
   }
   for (size_t i=0;i<BUF_SIZ;i+=infile.gcount())
   {
    char buf[BUF_SIZ];
    //read content from new file 
    //Fill the content when there is also have space in the last file
    if (0 != atoi(bendpos))
    {
     if (infile.read(buf,(BUF_SIZ - atoi(bendpos))))
     {
      outfile.write(buf,(BUF_SIZ - atoi(bendpos)));
      strcpy(bendpos,"0");    
      break;
     }
    }
    if (infile.read(buf,BUF_SIZ))
    {
     outfile.write(buf,BUF_SIZ);
    }else
    {
     //buf[infile.gcount()]='/0';
     outfile.write(buf,infile.gcount());
     isEnd = TRUE;
     //record FILE start and end pos. 
     //ostringstream startpos;
     ostringstream endpos;
     //startpos<<;
     endpos<<infile.gcount();
     WritePrivateProfileString(srcName.c_str(),"EndFile",
      oss.str().c_str(),"./docid.pos");
     WritePrivateProfileString(srcName.c_str(),oss.str().c_str(),
      endpos.str().c_str(),"./docid.pos");
     //record last file information.
     WritePrivateProfileString("Config","LastFile",
      oss.str().c_str(),"./docid.pos");
     WritePrivateProfileString("Config","LastFilePos",
      endpos.str().c_str(),"./docid.pos");
     //To save one variable,use endpos to store cnt.
     endpos.str("");
     endpos<<(--cnt);
     WritePrivateProfileString("Config","ID",endpos.str().c_str(),"./docid.pos");
     outfile.close();
     break;
    }
    outfile.close();
   }
  }
  infile.close();
  return TRUE;
 }
 
 int mergeSliceToNormal(const string &srcName)
 {
  SetCurrentDirectory("./");

  ostringstream newFile;
  newFile<<srcName.c_str()<<".new";

  ofstream outfile(newFile.str().c_str(),ios_base::binary);
  char startFile[64];
  char endFile[64];
  char endpos[4];
  char currentendpos[8];

  bool firstVisit = FALSE;

  GetPrivateProfileString(srcName.c_str(),"StartFile","",startFile,64,"./docid.pos");
  GetPrivateProfileString(srcName.c_str(),"EndFile","",endFile,64,"./docid.pos");

  char tmpEndFile[64];
  GetPrivateProfileString((filelist[filelist.size()-1]).c_str(),"EndFile","",tmpEndFile,64,"./docid.pos");
  GetPrivateProfileString((filelist[filelist.size()-1]).c_str(),tmpEndFile,"",endpos,4,"./docid.pos");
  if (!strcmp(startFile,"tmp.0"))
  {
   firstVisit = TRUE;
  }

  char tmp[] = "tmp.";
  char *startFilePos = NULL;
  char *endFilePos = NULL;

  startFilePos = strtok(startFile,tmp);
  endFilePos = strtok(endFile,tmp);

  for (int i = atoi(startFilePos);i<=atoi(endFilePos);i++)
  {
   ostringstream oss;
   char buf[BUF_SIZ];
   oss<<"tmp."<<i;
   ifstream infile(oss.str().c_str(),ios_base::binary);
   //if it was the first visit,you should seek the the begin pos in
   // the last file.
   if (!firstVisit)
   {
    infile.seekg(atoi(endpos));
    firstVisit = TRUE;

    if (infile.read(buf,(BUF_SIZ - atoi(endpos))))
    {
     outfile.write(buf,(BUF_SIZ - atoi(endpos)));
    }else
    {
     outfile.write(buf,infile.gcount());
    }
    continue;
   }
   //if reach the last file, you should only read the length of buf 
   //which belonged this file.
   if (i == atoi(endFilePos))
   {
    GetPrivateProfileString(srcName.c_str(),oss.str().c_str

(),"",currentendpos,8,"./docid.pos");

    if (infile.read(buf,atoi(currentendpos)))
     outfile.write(buf,atoi(currentendpos));
    break;
   }
   if (infile.read(buf,BUF_SIZ))
   {
    outfile.write(buf,BUF_SIZ);
   }else
   {
    outfile.write(buf,infile.gcount());
   }
   infile.close();
  }
  outfile.close();
  return TRUE;
 }

}

Testing:

 FILESPLIT::initConfig();
 FILESPLIT::splitGreatToSlice("c://vs//first.exe");
 FILESPLIT::splitGreatToSlice("c://vs//second.exe");

 FILESPLIT::mergeSliceToNormal("c://vs//first.exe");
 FILESPLIT::mergeSliceToNormal("c://vs//second.exe");

原创粉丝点击