cambaluc的个人博客分享 http://blog.sciencenet.cn/u/cambaluc

博文

用小C程序批量处理大文件

已有 4980 次阅读 2015-4-3 18:02 |个人分类:c|系统分类:科研笔记| C语言, 文件

   没研究过什么大数据,但工作中确实碰到过很多很多数据文件需要处理。有时候文件真是多得不得了。
   一、几年前一个台站搞数据测量的说硬盘有问题了,无法打开数据文件夹,我检测了一下发现硬盘好的。原来文件夹下每分钟生成一组测量数据文件,几年下来文件太多,是windows的资源管理器无法打开文件夹,挂到另一台计算机上用DOS命令还能访问,于是编写了几行C程序,把几百万个文件合并起来,读取了有用的数据,导入到数据库中,解决了问题。
   二、去年我们图书馆的服务器出问题了,厂家的工程师来发现硬盘空间不足了,莫名其妙在主机硬盘上生成好多文件,但不知道是在哪个文件夹下文件异常多,反正unix系统下文件夹很多,嵌套关系很深。为了弄清哪些目录下文件最多,他先编写unix命令把两块硬盘目录及各目录的文件计数输出到文本,不料生成的两文本大小都达400多兆,一般的编辑软件打不开,厂家工程师用linux的一软件打开后也只能手工查看文件数量,翻看了一个多小时没个头绪。我想先把数据导入sql数据库,转换起来也很慢,没成功,更不用说排序了。于是我写了以下程序,很快检索出具有哪些目录文件数异常,发现几个目录下有上亿个文件。
void main()
{   FILE *fp,*fp1;
  char t[1000], r[1000];
  long i=0;
     if((fp=fopen("ionde-252.txt","r"))==NULL)
  {printf("cannot open filen");
  exit(0) ;}
       if((fp1=fopen("iondeqw_out2.txt","w+"))==NULL)
  {printf("cannot open filen");
  exit(0) ;}
    char a[6],b[9];
  while(!feof(fp)){
   i++;
   strcpy(r,t);
   fgets(t,50,fp);
   sscanf(t,"%s %s",a,b);
   if(strcmp(a,"total")==0 && atoi(b)>10000000 )
  { fprintf(fp1,"%ld %s %sn",i,a,b);
     fprintf(fp1,"%sn",r);
    }
  }
 fclose(fp);
 fclose(fp1);
}
输出了如下格式的文件:
1836017712 total 51130400
./export/home/oracle/huiwen_bak
1919889265 total 11293966
./u01/app/oracle/admin/orcl/adump
959591217 total 21394189
./proc/20329
959853106 total 21391264
./proc/21269
并最终找出了异常的文件夹,解决了问题。
  三、这几天处理文件又用到了C语言,我们一位老师收集来一大堆(只能用这词)电子文档,多数是PDF文件,我们想打印出来,需统计有多少文件、每个PDF有多少页、估计打印多少册,打印稿目录和电子文件夹也应该对应。移动硬盘上的文件目录嵌套很深,各式文件很杂,人工处理工作量很大,印刷厂人也不好接手。
    于是,我先写了如下程序,处理了问题。用C程序读取了PDF文件中的总页数。Perl有很优秀的文件、目录处理功能,用perl把树型的目录转为线型的列表输出到一个allfile.txt文件中(相当于用dir /p/s >allfile.txt,但用程序处理的目的是得到规则的完整文件路径)。perl程序中调用C语言写的readPDF.exe读取每个遍历到的PDF文件的页数。
////读取一个pdf文件的总页数的程序,文中省略了出错处理及部分特殊格式pdf文件的处理/////
#include <stdio.h>
#include <stdlib.h>
void main(int argc,char *argv[])
{
  FILE *fp;
 // long i=0;
  int j;
  char v;
  char a_count[20];

  if((fp=fopen(argv[1],"rb"))==NULL)
    {printf("can not open filen");
     exit(0);}
j=0;
  while(!feof(fp))
  {fread(&v,1,1,fp);
      //printf("%c",v);
 if(v=='/')
 {   fread(&v,1,1,fp);//printf("%c",v);
     if(v=='N')
  { fread(&v,1,1,fp);
      if(v==' ')
   {fread(&v,1,1,fp);
     while(v>='0'&&v<='9')  
     {
                  a_count[j++]=v;
                   fread(&v,1,1,fp);
     }
                  a_count[j++]='';
   }
            printf("%s",a_count);
  break;
  }
 }
  }
  fclose(fp);
}
///////////////////
#!/Perl/bin/perl -w
#$PATH="F:/kj_file_access/pdf_file/article";
$PATH="F:/GX-selected Books for Printing";
open(F_ALL,">F:/kj_file_access/allfile.txt");
&FindDir($PATH);
sub FindDir
{
   my ($path,$DIR)=@_;
if(chdir($path))
{
  opendir($DIR,$path);
  my $line=readdir($DIR);
  while ($line)
 {
  if($line ne '.' && $line ne '..')
   {
if(chdir("$path/$line"))
{
     FindDir("$path/$line");
}
else
{       my $dirfile="$path/$line";
 my $countpage=0;
               if($dirfile=~/.pdf/)
 {   #$countpage=`F:/kj_file_access/readPDF.exe $dirfile`;
 $countpage=qx(F:/kj_file_access/readPDF.exe "$dirfile");
                }
     print F_ALL "$dirfile,$countpagen";
}
    }
  $line=readdir($DIR);
  }
closedir($DIR);
}
}
close(F_ALL);
   最终很好的处理了文件并编排了目录,C语言还是很好用的,比其它windows软件处理数据快多了,这个问题我试着用excel的VBA做过,处理速度很慢。
   我的一些学生常觉得学这用处不大,不想学,尤其是不想过学校要求的二级考试,写此文说明一下,学点C语言、学点编程还是用的到的。

 



https://blog.sciencenet.cn/blog-797552-879614.html

上一篇:大理,苍山
下一篇:学三角多项式逼近和快速傅立叶变换(一)
收藏 IP: 111.63.12.*| 热度|

4 姬扬 罗汉江 peosim yangb919

该博文允许注册用户评论 请点击登录 评论 (2 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-28 05:14

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部