• perl处理文本文件抛出out of memory


    造成问题的原因是处理的文本文档有2g大小。

    #2016.10.21 by ouyanga
    #合并所有的词频文件到$result目录下de最终词频
    
    my $fileDir=shift @ARGV or die "$!";
    my $result;
    
    $result=$fileDir."\最终词频";
    
    mkdir $result;
    
    my $filepath=$fileDir."\文件名.log";
    my @dir; 
    
    opendir (DIR, $fileDir);
    @dir = readdir DIR;
    
    open(out1, ">$filepath"); #输入
    
    foreach $file (@dir) 
    { 
           if( $file =~ /.txt$/)
        {
            print out1 $fileDir."\".$file."
    ";
        } 
    
    } 
    close(out1);
    
    open (in2,$filepath);
    
    #遍历包含文件名的列表
    while($filename=<in2>){
        chomp($filename);
        
        print "read file ".$filename."
    ";
        
        open(inTmp2, $filename) or die "cannot open ".$filename."
    ";
    
        while(defined($word=<inTmp2>)){
            chomp($word);
            
            split("	",$word);
                    
            $words{$_[0]}+=$_[1];
                
        }
        close(inTmp2);
    }
    close(in2);
    
    $result=$result."\最终词频.txt";
    
    open(out2,">".$result) or die "can not open". $result."
    ";
    
    foreach $w (sort keys %words){
        print out2 $w."	".$words{$w}."
    ";
    }
    close(out2);
    
    print "game over.
    ";

     解决方法:

    对文件的内容进行hash,分解成多个小文件。

    然后合并小文件里面重复的词。

    再把小文件写到一个文件里面。

    #2016.10.21 by ouyanga
    #1.顺序读取文件,对于每个词Hash(x)%31。然后按着值存放到31个文件中。
    #2.针对每个文件,统计词以及频率
    #3.合并31个文件为一个文件
    
    use Encode; 
    my $fileDir=shift @ARGV or die "$!";#包含待处理文件的目录
    my $result;
    
    $result=$fileDir."\分而治之";
    
    mkdir $result;
    
    my $filepath=$fileDir."\文件名.log";
    my @dir; 
    
    opendir (DIR, $fileDir);
    @dir = readdir DIR;
    
    open(out1, ">$filepath"); #输入
    
    foreach $file (@dir) 
    { 
           if( $file =~ /.txt$/)
        {
            # 统计目录下得所有文件
            print out1 $fileDir."\".$file."
    ";
        } 
    
    } 
    
    close(out1);
    
    open (in2,$filepath);
    
    my $hash_value=31;
    my %result_dir;
    
    my $hashValue=31;
    while($hashValue!=-1)
    {
        $result_dir{$hashValue}="hash".$hashValue.".txt";
        --$hashValue;
    }
    
    #遍历包含文件名的列表
    while(defined($filename=<in2>)){
    
        chomp($filename);
        
        print "read file ".$filename."
    ";
        
        open(inTmp2, $filename) or die "cannot read open ".$filename."
    ";
    
        # 对文件里面的词进行hash映射
        while(defined($word=<inTmp2>)){
            chomp($word);
            
            split(/	/,$word);
            
            my $str=decode("gb2312",$_[0]); 
    
            @chars=split (//,$str);
         
            my $c=0;    #=ord($chars[0]);#ord把gb2312编码转为十进制。
            
            foreach $tc(@chars){
                                    
                $c=$c*31+ord($tc);
            }
            
            $hash_value= $c%31;
            
            my $resultTxt=$result."\".$result_dir{$hash_value};
            
            open(out2,">>".$resultTxt) or die "can write not open ". $resultTxt.". calcultate hash value is : $hash_value.
    ";#追加内容
            
            print out2 $word."
    ";
            
            close(out2);
        }
        
        close(inTmp2);
    }
    
    close(in2);
    
    print "game over.
    ";
  • 相关阅读:
    进程间多线程同步三种方法
    C++ 生成随机数 srand()和rand()
    事件对象用于多线程之间的同步
    $.ajax()方法参数详解
    面向对象的属性
    对多选框进行操作,输出选中的多选框的个数
    jQuery如何检查某个元素在网页上是否存在
    关于$.fn
    c#基础班笔记
    Sublime Text 3的快捷键
  • 原文地址:https://www.cnblogs.com/363546828/p/5983691.html
Copyright © 2020-2023  润新知