• 热门专题

C语言打包解包文件程序

作者:  发布日期:2012-12-27 09:17:56
Tag标签:C语言  
  • //测试通过 科嵌电子  
     
    #include <stdio.h>   
    #include <string.h>   
    #include <stdlib.h>   
       
    typedef unsigned int  uint;   
    typedef unsigned char byte;              
       
    // 包文件中最大可容纳的文件个数   
    #define MAX_FILE_COUNT 10   
       
    // 全局包文件指针   
    FILE*  g_pMasFile = NULL;   
     
    // 资源包文件头结构   
    typedef struct SMaseFileHeader   
    {   
     uint  uFileFlag;         // 包文件头标记: 'MASE'   
     uint  uFileCount;        // 包内文件个数   
     uint  uFileListOfs;      // 文件列表偏移   
     uint  uMaxFileCount;     // 最大子文件个数   
     uint  uFileSize;         // 包文件的大小   
    }MaseHeader;   
       
    // 包内文件信息结构   
    typedef struct SFilesMessage   
    {   
     uint  uFileOfs;          // 本文件在包内的偏移   
     uint  uFileSize;         // 本文件的大小   
     char  szFileName[260];   // 本文件的路径   
    }FilesMsg;   
     
    // 打开包文件   
    int OpenMasFile(const char* path, const byte onlyOpen)   
    {   
     uint       uWriteCount;       // 写入文件信息次数   
     byte       bIsNew = 0;        // 是否新建的   
     MaseHeader header;            // 文件头结构定义   
     FilesMsg   msg;               // 文件信息结构定义  
     
     g_pMasFile = fopen(path, "rb");  // 用来判断是否存在   
     if (g_pMasFile == NULL)        
     {   
      if (onlyOpen == 1)            // 只打开不新建   
       return -1;    
       
      bIsNew = 1;   
      g_pMasFile = fopen(path, "wb");   
      if (g_pMasFile == NULL)   
       return -1;   
     }   
     
     //先关闭,然后在用"rb+"方式打开  二进制读写打开文件  
     fclose( g_pMasFile );   
     
     g_pMasFile = fopen(path, "rb+");   
     if (g_pMasFile == NULL)   
      return -1;   
       
     if(bIsNew == 1)// 新建的文件   
     {   
      header.uFileFlag     = 'ESAM';   
      header.uFileCount    = 0;   
      header.uFileListOfs  = sizeof(MaseHeader); //紧跟着就是文件列表   
      header.uMaxFileCount = MAX_FILE_COUNT;   
      header.uFileSize     = sizeof(MaseHeader)    
              + (MAX_FILE_COUNT * sizeof(FilesMsg));   
     
      //写入头信息   
      fwrite(&header, sizeof(MaseHeader), 1, g_pMasFile);   
      memset(&msg, 0, sizeof(FilesMsg));   
      uWriteCount = MAX_FILE_COUNT;   
     
      //写入文件列表用0占位   
      while(uWriteCount--)   
         fwrite(&msg, sizeof(FilesMsg), 1, g_pMasFile);   
     }   
     else//文件存在   
     {   
        //则读取头文件信息   
        fread(&header, sizeof(MaseHeader), 1, g_pMasFile);   
     }   
     
     //检查文件头标记   
     if (header.uFileFlag != 'ESAM')   
     {   
      fclose(g_pMasFile);  
      printf("文件头标记不对,错误!\n");  
      return -1;   
     }   
       
     //检查数据是否完整   
     if (header.uMaxFileCount != MAX_FILE_COUNT)   
     {   
      fclose(g_pMasFile);   
      printf("数据不完整,错误!\n");  
         return -1;   
     }   
       
     return 0;   
    }   
       
    //写文件到包里   
    int WriteFileToPak(const char* path)   
    {   
     FilesMsg   fileMsg;      //此文件的文件信息结构   
     MaseHeader header;       //包文件头结构定义   
     uint       uFileSize;   
     uint       uFileListEndOfs;   
     byte*      pBuff;   
     FILE*      pFile = NULL;   
       
     if (g_pMasFile == NULL)   
         return -1;   
       
     memset(&fileMsg, 0, sizeof(FilesMsg));   
     fseek(g_pMasFile, 0, SEEK_SET);    //定位到文件头,读取头文件信息  
       
     //则读取头文件信息   
     fread(&header,sizeof(MaseHeader), 1, g_pMasFile);   
       
     uFileListEndOfs = header.uFileCount * sizeof(FilesMsg) + header.uFileListOfs;   
       
     pFile = fopen(path, "rb");   
     if(pFile == NULL)   
         return -1;   
       
     fseek(pFile, 0, SEEK_END);   
     uFileSize = ftell(pFile);   
     fseek(pFile, 0, SEEK_SET);   
       
     //文件名长度不能超过260   
     strcpy(fileMsg.szFileName,path);   
     fileMsg.uFileOfs  = header.uFileSize;   
     fileMsg.uFileSize = uFileSize;   
       
     // 写入文件信息   
     // 将文件指针定位到uFileListEndOfs处,以便写入新的文件信息结构   
     fseek(g_pMasFile, uFileListEndOfs, SEEK_SET);   
     fwrite(&fileMsg,sizeof(FilesMsg),1,g_pMasFile);   
       
     // 申请空间   
     pBuff = (byte*)malloc(uFileSize);   
     fread(pBuff,uFileSize,1,pFile);   
       
     // 写数据到包文件里   
     fseek(g_pMasFile,header.uFileSize,SEEK_SET);   
     fwrite(pBuff, uFileSize, 1, g_pMasFile);   
       
     // 释放内存   
     free(pBuff);   
       
     //重新填充header   
     header.uFileCount += 1;   
     header.uFileSize  += uFileSize;   
       
     fseek( g_pMasFile,0,SEEK_SET);   
       
     // 重新写入包文件头   
     fwrite(&header,sizeof(MaseHeader),1,g_pMasFile);   
       
     return 0;   
    }   
       
    //从包文件里读数据   
    int ReadFileFromPak(const FilesMsg msg, byte* _dst)   
    {   
     if ( g_pMasFile == NULL )   
         return -1;   
       
     fseek(g_pMasFile, msg.uFileOfs,SEEK_SET);   
     fread(_dst, msg.uFileSize, 1, g_pMasFile);   
       
     return 0;   
    }   
       
    //获取包中某个文件的信息   
    int GetFileMessage( const char* path, FilesMsg* msg)   
    {   
     FilesMsg   fileMsg;      // 此文件的文件信息结构   
     MaseHeader header;       // 包头结构   
     uint       uFileCount;   // 文件个数   
       
     if ( g_pMasFile == NULL || msg == NULL )   
         return -1;   
       
     // 则读取头文件信息   
     fseek(g_pMasFile, 0, SEEK_SET);   
     fread(&header, sizeof(MaseHeader), 1, g_pMasFile);   
       
     uFileCount = header.uFileCount;   
     while (uFileCount--)   
     {   
         fread(&fileMsg, sizeof(FilesMsg), 1,g_pMasFile);   
     
         // 判断是否是要获取的文件   
         if (stricmp(fileMsg.szFileName, path) == 0 )   
         {               
       *msg = fileMsg;   
             return 0;   
         }   
     }   
     return -1;   
    }   
       
    // 关闭包文件   
    int CloseMasFile( void )   
    {   
     if ( g_pMasFile == NULL )   
         return -1;   
       
     fclose( g_pMasFile );   
     g_pMasFile = NULL;   
       
     return 0;   
    }  
    //这是打包主函数  
     
    int main( void )   
    {   
     int ret;   
       
     ret = OpenMasFile( "E:\\PhotoPak.bin",0);   
     if ( ret == -1 )   
         goto __exit;      
     WriteFileToPak( "E:\\珍贵.jpg" );   
     WriteFileToPak( "E:\\123.docx" );   
     WriteFileToPak( "E:\\456.txt" );   
     
     __exit:   
     CloseMasFile();   
     return 0;   
    }    
    //查看打包中的文件,并且可以解包查看  
     
    int main( void )   
    {   
     byte*       pBuff;   
     FILE*       pOutFile;   
     FilesMsg    getFileMsg;   
     int         ret;   
       
     ret = OpenMasFile("E:\\PhotoPak.bin", 1);   
     if (ret == -1)   
        goto __exit;   
        
     ret = GetFileMessage("E:\\123.docx", &getFileMsg);   
     if(ret == -1)   
        goto __exit;   
       
     pBuff = (byte*)malloc(getFileMsg.uFileSize);   
     ret = ReadFileFromPak(getFileMsg, pBuff);   
     if(ret == -1)   
         goto __exit_free;   
       
     pOutFile = fopen("E:\\123_out.docx", "wb");  // 注意使用的是二进制模式   
     if(ret == -1)   
         goto __exit_free;   
        
     fwrite( pBuff, getFileMsg.uFileSize, 1, pOutFile );   
        fclose( pOutFile );   
            
     __exit_free:   
     free( pBuff );   
       
     __exit:   
        CloseMasFile();   
        return 0;   
    }  
    
    

     

延伸阅读:

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规