FFCREATE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation.  All Rights Reserved.
  4.  *
  5.  *  File:       ffcreate.c
  6.  *  Content: Fast file I/O for large numbers of files.
  7.  * Turns all files in a directory into a single file.
  8.  * This single file contains a directory + all the files.
  9.  *
  10.  * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  11.  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  12.  * WARRANTIES OF MERCHANTBILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  13.  *
  14.  ***************************************************************************/
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <systypes.h>
  21. #include <sysstat.h>
  22. #include <fcntl.h>
  23. #include <io.h>
  24. #include <malloc.h>
  25. #ifdef __WATCOMC__
  26. #define _open open
  27. #define _close close
  28. #define _lseek lseek
  29. #define _read read
  30. #define _write write
  31. #define _stricmp stricmp
  32. #define _S_IREAD S_IREAD
  33. #define _S_IWRITE S_IWRITE
  34. #endif
  35. #include "ffent.h"
  36. #define BLOCK_SIZE 16*1024
  37. /*
  38.  * Compare
  39.  *
  40.  * quicksort comparison routine
  41.  */
  42. int Compare( const LPFILEENTRY p1, const LPFILEENTRY p2 )
  43. {
  44.     return( _stricmp( (p1)->name,(p2)->name ) );
  45. }
  46. /*
  47.  * main
  48.  */
  49. main( int argc, char *argv[] )
  50. {
  51.     HANDLE dir;
  52.     WIN32_FIND_DATA fd;
  53.     int out;
  54.     int in;
  55.     unsigned long cnt;
  56.     unsigned long tmp;
  57.     LPFILEENTRY pfe;
  58.     int i;
  59.     int bytes;
  60.     int outbytes;
  61.     char *buff;
  62.     char *fname;
  63.     char *dename;
  64.     long pos;
  65.     /*
  66.      * get i/o buffer
  67.      */
  68.     buff = malloc( BLOCK_SIZE );
  69.     if( buff == NULL ) {
  70. printf( "Out of memory!n" );
  71. exit( 1 );
  72.     }
  73.     /*
  74.      * get fastfile name, open file
  75.      */
  76.     if( argc < 2 ) {
  77. fname = "\result.ff";
  78.     } else {
  79. fname = argv[1];
  80.     }
  81.     printf( "Creating FastFile "%s"n", fname );
  82.     out = _open( fname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY,
  83.      _S_IREAD | _S_IWRITE );
  84.     if( out < 0 ) {
  85. printf( "Could not open file "%s"", fname );
  86. exit( 1 );
  87.     }
  88.     /*
  89.      * build a header
  90.      */
  91.     cnt = 0;
  92.     printf( "Pass 1: building headern" );
  93.     dir = FindFirstFile( "*.*", &fd );
  94.     if( dir == NULL ) {
  95. printf( "Could not open current directoryn" );
  96. _close( out );
  97. exit( 1 );
  98.     }
  99.     pfe = NULL;
  100.     while( 1 ) {
  101. if( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
  102.     cnt++;
  103.     pfe = realloc( pfe, (cnt+1) * sizeof( FILEENTRY ) );
  104.     memset( &pfe[cnt-1], 0, sizeof( FILEENTRY )*2 );
  105.     if( pfe == NULL ) {
  106. printf( "Out of memory!n" );
  107. _close( out );
  108. exit( 1 );
  109.     }
  110.     dename = fd.cAlternateFileName;
  111.     if( dename[0] == 0 ) {
  112. dename = fd.cFileName;
  113.     }
  114.     printf( "File %d: %s                 r", cnt, dename );
  115.     pfe[cnt-1].offset = 0;
  116.     strcpy( pfe[cnt-1].name, dename );
  117. }
  118. if( !FindNextFile( dir, &fd ) ) {
  119.     break;
  120. }
  121.     }
  122.     FindClose( dir );
  123.     if( cnt == 0 ) {
  124. printf( "No files found!n" );
  125. exit( 0 );
  126.     }
  127.     /*
  128.      * sort the directory
  129.      */
  130.     qsort( pfe, cnt, sizeof( FILEENTRY ), (LPVOID) Compare );
  131.     /*
  132.      * write the number of directory entries + the directory
  133.      */
  134.     tmp = cnt+1;
  135.     bytes = _write( out, &tmp, sizeof( tmp ) );
  136.     if( bytes != sizeof( tmp ) ) {
  137. printf( "Error writing output filen" );
  138. _close( out );
  139. exit( 1 );
  140.     }
  141.     bytes = _write( out, pfe, tmp * sizeof( FILEENTRY ) );
  142.     if( bytes != (int) (tmp * sizeof( FILEENTRY )) ) {
  143. printf( "Error writing output filen" );
  144. _close( out );
  145. exit( 1 );
  146.     }
  147.     /*
  148.      * now read all of the files one by one and add them to the fastfile
  149.      */
  150.     printf( "Pass 2: adding data files                  n" );
  151.     for( i=0;i<(int)cnt;i++ ) {
  152. /*
  153.  * save current file position
  154.  */
  155. pfe[i].offset = _lseek( out, 0, SEEK_CUR );
  156. if( pfe[i].offset < 0 ) {
  157.     printf( "nSeek error on output filen" );
  158.     _close( out );
  159.     exit( 1 );
  160. }
  161. /*
  162.  * open next file to add
  163.  */
  164. in = _open( pfe[i].name, O_RDONLY | O_BINARY, 0 );
  165. printf( "File %d: "%s", offset=%ld                          r",
  166. i+1, pfe[i].name, pfe[i].offset );
  167. if( in < 0 ) {
  168.     printf( "nError opening file %sn", pfe[i].name );
  169.     _close( out );
  170.     exit( 1 );
  171. }
  172. /*
  173.  * copy the data in the file
  174.  */
  175. while( 1 ) {
  176.     bytes = _read( in, buff, BLOCK_SIZE );
  177.     if( bytes == 0 ) {
  178. break;
  179.     }
  180.     if( bytes < 0 ) {
  181. printf( "nError reading file %sn", pfe[i].name );
  182. _close( in );
  183. _close( out );
  184. exit( 1 );
  185.     }
  186.     outbytes = _write( out, buff, bytes );
  187.     if( bytes != outbytes ) {
  188. printf( "nError writing output filen" );
  189. _close( in );
  190. _close( out );
  191. exit( 1 );
  192.     }
  193.     if( bytes < BLOCK_SIZE ) {
  194. break;
  195.     }
  196. }
  197. _close( in );
  198.     }
  199.     /*
  200.      * get position of file end
  201.      */
  202.     pfe[i].offset = _lseek( out, 0, SEEK_CUR );
  203.     /*
  204.      * seek to the start of the directory (right after the # of entries)
  205.      */
  206.     pos = _lseek( out, sizeof( tmp ), SEEK_SET );
  207.     if( pos != sizeof( tmp ) ) {
  208. printf( "Seek error on output filen" );
  209. _close( out );
  210. exit( 1 );
  211.     }
  212.     /*
  213.      * re-write the directory with the offsets setup
  214.      */
  215.     bytes = _write( out, pfe, tmp * sizeof( FILEENTRY ) );
  216.     if( bytes != (int) (tmp * sizeof( FILEENTRY )) ) {
  217. printf( "Error writing output filen" );
  218. _close( out );
  219. exit( 1 );
  220.     }
  221.     /*
  222.      * all done
  223.      */
  224.     printf( "FastFile "%s" created:                   n", fname );
  225.     printf( "    %ld filesn", tmp );
  226.     printf( "    %ld total file sizen", pfe[i].offset );
  227.     _close( out );
  228.     return 0;
  229. } /* main */