免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10959 | 回复: 18
打印 上一主题 下一主题

linux 下将大文件拆分处理 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-12-27 14:48 |只看该作者 |倒序浏览
Hi
本人想写一个处理速度更高的文件处理程序
特此请教!

下面代码只是每次读取文件一行来处理
将一个大文件(例如10G),拆分成500个表来保存
文件内容是
4,53,62
6553,5,42
853,65,45
722,55,74
......
...

想更高效率就需要每次取 几M 到内存再处理
所以下面代码有待改善
有人能分享下怎样从这个大文件抽取 几M(1M或5M)到内存再进行处理吗???(我代码是对每行的  , 之前的数字取模,按照模数来分表)

或者有人有更好的想法吗?

关于处理大文件的想法欢迎一起讨论!
谢谢!

  1. #include <iostream>
  2. #include <fstream>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>

  6. using namespace std;

  7. //找到  , 之前的数字
  8. int GetNumber(char *text, char c)
  9. {
  10.         int len = strlen(text);
  11.         int num = 0;
  12.         int k = 1;

  13.         int i = 0;
  14.         for(i=0;i<len;i++)
  15.         {
  16.                 if(text[i]==c)
  17.                 {
  18.                         break;
  19.                 }
  20.         }
  21.         i--;
  22.         for(;i>=0;i--)
  23.         {
  24.                 num = num + (text[i] - '0') * k;
  25.                 k *= 10;
  26.         }
  27.         return num;
  28. }
  29. //参数:要打开的文件名+拆分文件数
  30. int main(int argc, char *argv[])
  31. {
  32.         if(argc <= 1)
  33.         {
  34.                 cout<<"Input File Name"<<endl;
  35.                 return -1;
  36.         }
  37.         ifstream in(argv[1]);
  38.         char out_file_name[260];
  39.         ofstream *out = new
  40.         ofstream[atoi(argv[2])];///atoi
  41.         for(int i=0;i<atoi(argv[2]);i++)///atoi
  42.         {
  43.                 sprintf(out_file_name, "./test/test%d.txt", i+1);//这里修改输出地址
  44.                 out[i].open(out_file_name);
  45.         }

  46.         char s[128];//拆分后文件每行的宽度
  47.         int score_split;//保存取模之后结果,可以用作输出文件索引号
  48.         while(in.getline(s, 128))
  49.         {
  50.                 int score_split_line = GetNumber(s, ',');
  51.                 score_split = score_split_line%atoi(argv[2]);////atoi
  52.                 out[score_split].write(s, strlen(s) +1);//按照索引号将匹配到的行内容输出到对应的文件里
  53.                 out[score_split]<<endl;
  54.         }

  55.         for(int i=0;i<atoi(argv[2]);i++)////atoi
  56.         {
  57.                 out[i].close();//关闭打开的文件流
  58.         }

  59.         in.close();
  60.         return 0;
  61. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-12-27 15:11 |只看该作者
fread()不是可以一次读取一个块的么

论坛徽章:
0
3 [报告]
发表于 2010-12-27 15:13 |只看该作者
一次读取几M不一定效率就高吧??
隐约记得,貌似IO操作有个临界值还是什么,4096????

论坛徽章:
0
4 [报告]
发表于 2010-12-27 15:28 |只看该作者
lz先要确认哪部分操作是瓶颈.比如对文件中数字去掉重复等,cpu处理占大量时间的操作,那么先对文件拆分,在多核处理器的情况下用多线程处理会明显提高效率,但是如果只是对每行做些简单的运算,那么还是不要拆分的好,一个文件从头到尾读,这样相对效率更高,因为对驱动层来说,你多个线程读文件,那么总的io效率不如单个线程.

论坛徽章:
0
5 [报告]
发表于 2010-12-27 16:58 |只看该作者
回复 1# cllggg

我支持四楼:samlumengjun 兄的看法
楼主赶紧贴 硬件配置 以及 iostat 吧

论坛徽章:
0
6 [报告]
发表于 2010-12-27 17:46 |只看该作者
回复 4# samlumengjun

配置 3CPU   8G内存

其实我的想法是
如何将一个5G的文件 快速地拆分成 500 个文件来保存

拆分原则是将每行的  123,55,5   中的  ,  前的数取模(也就是 123%500)
以上这一行就分到了表 123.txt 里保存
如果第二行是  505,423,54  它就被分到表 5.txt 里保存
如此下去将整个文件分 500 个表来保存!!


好什么好的办法么?
谢谢!!

论坛徽章:
0
7 [报告]
发表于 2010-12-27 17:55 |只看该作者
你这种需求用mmap做比较好.

论坛徽章:
0
8 [报告]
发表于 2010-12-27 18:35 |只看该作者
回复 7# samlumengjun


将整个文件映射到内存里??
文件太大了,在服务器上的话,一时间也太费内存资源的了

论坛徽章:
0
9 [报告]
发表于 2010-12-27 20:24 |只看该作者
split

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:50:28
10 [报告]
发表于 2010-12-28 09:07 |只看该作者
先用gprof分析一下性能瓶颈吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP