home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / FASTFILE / FFCREATE.C < prev    next >
C/C++ Source or Header  |  1996-08-28  |  7KB  |  250 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1996 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 <sys\types.h>
  21. #include <sys\stat.h>
  22. #include <fcntl.h>
  23. #include <io.h>
  24. #include <malloc.h>
  25.  
  26. #ifdef __WATCOMC__
  27. #define _open open
  28. #define _close close
  29. #define _lseek lseek
  30. #define _read read
  31. #define _write write
  32. #define _stricmp stricmp
  33. #define _S_IREAD S_IREAD
  34. #define _S_IWRITE S_IWRITE
  35. #endif
  36.  
  37. #include "ffent.h"
  38.  
  39. #define BLOCK_SIZE      16*1024
  40.  
  41. /*
  42.  * Compare
  43.  *
  44.  * quicksort comparison routine
  45.  */
  46. int Compare( const LPFILEENTRY p1, const LPFILEENTRY p2 )
  47. {
  48.     return( _stricmp( (p1)->name,(p2)->name ) );
  49. }
  50.  
  51. /*
  52.  * main
  53.  */
  54. main( int argc, char *argv[] )
  55. {
  56.     HANDLE              dir;
  57.     WIN32_FIND_DATA     fd;
  58.     int                 out;
  59.     int                 in;
  60.     unsigned long       cnt;
  61.     unsigned long       tmp;
  62.     LPFILEENTRY         pfe;
  63.     int                 i;
  64.     int                 bytes;
  65.     int                 outbytes;
  66.     char                *buff;
  67.     char                *fname;
  68.     char                *dename;
  69.     long                pos;
  70.  
  71.     /*
  72.      * get i/o buffer
  73.      */
  74.     buff = malloc( BLOCK_SIZE );
  75.     if( buff == NULL ) {
  76.         printf( "Out of memory!\n" );
  77.         exit( 1 );
  78.     }
  79.  
  80.     /*
  81.      * get fastfile name, open file
  82.      */
  83.     if( argc < 2 ) {
  84.         fname = "\\result.ff";
  85.     } else {
  86.         fname = argv[1];
  87.     }
  88.     printf( "Creating FastFile \"%s\"\n", fname );
  89.     out = _open( fname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY,
  90.                 _S_IREAD | _S_IWRITE );
  91.     if( out < 0 ) {
  92.         printf( "Could not open file \"%s\"", fname );
  93.         exit( 1 );
  94.     }
  95.  
  96.     /*
  97.      * build a header
  98.      */
  99.     cnt = 0;
  100.     printf( "Pass 1: building header\n" );
  101.     dir = FindFirstFile( "*.*", &fd );
  102.     if( dir == NULL ) {
  103.         printf( "Could not open current directory\n" );
  104.         _close( out );
  105.         exit( 1 );
  106.     }
  107.     pfe = NULL;
  108.     while( 1 ) {
  109.         if( !(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
  110.             cnt++;
  111.             pfe = realloc( pfe, (cnt+1) * sizeof( FILEENTRY ) );
  112.             memset( &pfe[cnt-1], 0, sizeof( FILEENTRY )*2 );
  113.             if( pfe == NULL ) {
  114.                 printf( "Out of memory!\n" );
  115.                 _close( out );
  116.                 exit( 1 );
  117.             }
  118.             dename = fd.cAlternateFileName;
  119.             if( dename[0] == 0 ) {
  120.                 dename = fd.cFileName;
  121.             }
  122.             printf( "File %d: %s                 \r", cnt, dename );
  123.             pfe[cnt-1].offset = 0;
  124.             strcpy( pfe[cnt-1].name, dename );
  125.         }
  126.         if( !FindNextFile( dir, &fd ) ) {
  127.             break;
  128.         }
  129.     }
  130.     FindClose( dir );
  131.  
  132.     if( cnt == 0 ) {
  133.         printf( "No files found!\n" );
  134.         exit( 0 );
  135.     }
  136.  
  137.     /*
  138.      * sort the directory
  139.      */
  140.     qsort( pfe, cnt, sizeof( FILEENTRY ), (LPVOID) Compare );
  141.  
  142.     /*
  143.      * write the number of directory entries + the directory
  144.      */
  145.     tmp = cnt+1;
  146.     bytes = _write( out, &tmp, sizeof( tmp ) );
  147.     if( bytes != sizeof( tmp ) ) {
  148.         printf( "Error writing output file\n" );
  149.         _close( out );
  150.         exit( 1 );
  151.     }
  152.     bytes = _write( out, pfe, tmp * sizeof( FILEENTRY ) );
  153.     if( bytes != (int) (tmp * sizeof( FILEENTRY )) ) {
  154.         printf( "Error writing output file\n" );
  155.         _close( out );
  156.         exit( 1 );
  157.     }
  158.  
  159.     /*
  160.      * now read all of the files one by one and add them to the fastfile
  161.      */
  162.     printf( "Pass 2: adding data files                  \n" );
  163.     for( i=0;i<(int)cnt;i++ ) {
  164.         /*
  165.          * save current file position
  166.          */
  167.         pfe[i].offset = _lseek( out, 0, SEEK_CUR );
  168.         if( pfe[i].offset < 0 ) {
  169.             printf( "\nSeek error on output file\n" );
  170.             _close( out );
  171.             exit( 1 );
  172.         }
  173.  
  174.         /*
  175.          * open next file to add
  176.          */
  177.         in = _open( pfe[i].name, O_RDONLY | O_BINARY, 0 );
  178.         printf( "File %d: \"%s\", offset=%ld                          \r",
  179.                                 i+1, pfe[i].name, pfe[i].offset );
  180.         if( in < 0 ) {
  181.             printf( "\nError opening file %s\n", pfe[i].name );
  182.             _close( out );
  183.             exit( 1 );
  184.         }
  185.  
  186.         /*
  187.          * copy the data in the file
  188.          */
  189.         while( 1 ) {
  190.             bytes = _read( in, buff, BLOCK_SIZE );
  191.             if( bytes == 0 ) {
  192.                 break;
  193.             }
  194.             if( bytes < 0 ) {
  195.                 printf( "\nError reading file %s\n", pfe[i].name );
  196.                 _close( in );
  197.                 _close( out );
  198.                 exit( 1 );
  199.             }
  200.             outbytes = _write( out, buff, bytes );
  201.             if( bytes != outbytes ) {
  202.                 printf( "\nError writing output file\n" );
  203.                 _close( in );
  204.                 _close( out );
  205.                 exit( 1 );
  206.             }
  207.             if( bytes < BLOCK_SIZE ) {
  208.                 break;
  209.             }
  210.         }
  211.         _close( in );
  212.     }
  213.  
  214.     /*
  215.      * get position of file end
  216.      */
  217.     pfe[i].offset = _lseek( out, 0, SEEK_CUR );
  218.  
  219.     /*
  220.      * seek to the start of the directory (right after the # of entries)
  221.      */
  222.     pos = _lseek( out, sizeof( tmp ), SEEK_SET );
  223.     if( pos != sizeof( tmp ) ) {
  224.         printf( "Seek error on output file\n" );
  225.         _close( out );
  226.         exit( 1 );
  227.     }
  228.  
  229.     /*
  230.      * re-write the directory with the offsets setup
  231.      */
  232.     bytes = _write( out, pfe, tmp * sizeof( FILEENTRY ) );
  233.     if( bytes != (int) (tmp * sizeof( FILEENTRY )) ) {
  234.         printf( "Error writing output file\n" );
  235.         _close( out );
  236.         exit( 1 );
  237.     }
  238.  
  239.     /*
  240.      * all done
  241.      */
  242.     printf( "FastFile \"%s\" created:                   \n", fname );
  243.     printf( "    %ld files\n", tmp );
  244.     printf( "    %ld total file size\n", pfe[i].offset );
  245.  
  246.     _close( out );
  247.     return 0;
  248.  
  249. } /* main */
  250.