이 예제는 파일의 앞부분의 지정한 크기만큼을 삭제하고 그만큼 데이터를 앞으로 당겨주는 것입니다.
즉, LOG파일같은것을 다룰때 파일의 크기가 일정한 크기를 넘어섰을때 어떻게 빠르게 파일의 크기를 축소할수 있는지를 고민해보자는 취지에서 만들어 본것입니다.

코드:
/*
  Copyright (C) Information Equipment co.,LTD
  All rights reserved.
  Code by JaeHyuk Cho <mailto:minzkn@infoeq.com>
  CVSTAG="$Header$"
*/

#if defined(WIN32)
# include <io.h>
# include <windows.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#if !defined(O_BINARY)
# define O_BINARY 0
#endif
#if !defined(O_LARGEFILE)
# define O_LARGEFILE 0
#endif
#define def_max_block_size ((size_t)(4 << 10))

int main(int s_argc, char **s_argv)
{
 const char *s_filename;
 size_t s_reduce_size, s_buffer_size;
 int s_handle;
 void *s_buffer;
 off_t s_roffset, s_woffset, s_filesize;
 ssize_t s_read_bytes, s_write_bytes;

 if(s_argc <= 2){ (void)fprintf(stdout, "Usage: %s <filepath> <reduce_size>\n", s_argv[0]); return(0); }
 s_filename = s_argv[1], s_reduce_size = (size_t)atoi(s_argv[2]);
 if(s_reduce_size <= ((size_t)0)){ (void)fprintf(stdout, "invalid reduce size !\n"); return(1); }
 s_buffer_size = (s_reduce_size > def_max_block_size) ? def_max_block_size : s_reduce_size; /* buffer_size limit check */
 (void)fprintf(stdout, "debug: buffer_size=%lu\n", (unsigned long)s_buffer_size);
 s_handle = open(s_filename, O_RDWR | O_BINARY | O_LARGEFILE);
 if(s_handle == (-1)){ (void)fprintf(stdout, "can not open file ! (filename=\"%s\")\n", s_filename); return(1); }

 s_filesize = lseek(s_handle, (off_t)0, SEEK_END);
 if(s_filesize != ((off_t)(-1)))
 {
  s_buffer = malloc(s_buffer_size), s_roffset = (off_t)s_reduce_size, s_woffset = (off_t)0;
  if(s_buffer != ((void *)0))
  {
   do
   {
    if(lseek(s_handle, s_roffset, SEEK_SET) == ((off_t)(-1)))break;
    s_read_bytes = read(s_handle, s_buffer, s_buffer_size);
    if(s_read_bytes <= ((ssize_t)0))break;
    s_roffset += (off_t)s_read_bytes;
    if(lseek(s_handle, s_woffset, SEEK_SET) == ((off_t)(-1)))break;
    s_write_bytes = write(s_handle, s_buffer, (size_t)s_read_bytes);
    if(s_write_bytes <= ((ssize_t)0))break;
    s_woffset += (off_t)s_write_bytes;
   }while(1);
   free(s_buffer);
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
   (void)fprintf(stdout, "truncate %llu -> %llu bytes\n", (unsigned long long)s_filesize, (unsigned long long)s_woffset);
   (void)ftruncate(s_handle, s_woffset); /* POSIX */
#elif defined(WIN32)
   (void)fprintf(stdout, "truncate %lu -> %lu bytes\n", (unsigned long)s_filesize, (unsigned long)s_woffset);
   (void)chsize(s_handle, s_woffset);
#else
# warning not supported (f)truncate | chsize
#endif
  }
  else { (void)fprintf(stdout, "not enough memory\n"); return(1); }
 }
 else { (void)fprintf(stdout, "seek not supported\n"); return(1); }
 (void)close(s_handle);

 return(0);
}

/* vim: set expandtab: */
/* End of source */
크리에이티브 커먼즈 라이센스
Creative Commons License
Posted by minzkn

트랙백 주소 :: http://blog.minzkn.com/trackback/133

댓글을 달아 주세요