Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何读取两个大文件并比较内容_Php_Fopen - Fatal编程技术网

Php 如何读取两个大文件并比较内容

Php 如何读取两个大文件并比较内容,php,fopen,Php,Fopen,我要做的是读取大文件5.6GB,大约有6亿行,第二个是16MB,有2M行 我想检查这两个文件中的重复行 $wordlist = array_unique(array_filter(file('small.txt', FILE_IGNORE_NEW_LINES))); $duplicate = array(); if($file = fopen('big.txt', 'r')){ while(!feof($file)){ $lines = rtrim(fgets($file

我要做的是读取大文件5.6GB,大约有6亿行,第二个是16MB,有2M行

我想检查这两个文件中的重复行

$wordlist = array_unique(array_filter(file('small.txt', FILE_IGNORE_NEW_LINES)));
$duplicate = array();
if($file = fopen('big.txt', 'r')){
    while(!feof($file)){
        $lines = rtrim(fgets($file));
        if(in_array($lines, $wordlist)){
            echo $lines." : exists.\n";
        }
    }
    fclose($file);
}
但这需要很长时间才能完成(它已经运行了6个小时,但尚未完成:/)

我的问题是。有没有更好的方法快速搜索大文件?

我想

 $wordlist=array_flip(array_unique(array_filter(file('small.txt', FILE_IGNORE_NEW_LINES))));
您在代码中实际使用的单词会减慢速度。最好只构建一次单词列表,然后自己创建:

if($file1 = fopen('big.txt', 'r')){
    if($file = fopen('small.txt', 'r')){
        while(!feof($file)){
            $line=trim(fgets($file));
            if(!isset($wordlist[$line])&&!ctype_space($line)&&!empty($line)){
                $wordlist[$line]=0;
            }
        }
        fclose($file); 
    }
    while(!feof($file1)){
        $line1 = trim(fgets($file1));
        if(isset($wordlist[$line1]))
            $wordlist[$line1]++;            
    }
  fclose($file1); 
}
在此步骤中,变量$wordlist包含small.txt文件中所有行的列表以及big.txt文件中每行出现的次数。
您可以使用这样的数组或对其进行过滤以删除空行。您还可以使用uasort对数组进行排序,以了解更多关于哪些行出现最多,哪些行出现较少的信息,甚至可以进一步分析…

您无需调用
数组过滤器()
数组唯一()
如果要调用
array\u flip()
——它将为您消除重复项,因为在同一级别的数组中不能有重复的键

此外:

  • array\u unique()
  • array\u filter()
    在清除虚假/空/空/零ish数据方面名声不好,因此我要提醒您不要使用其默认行为
  • array\u flip()
    设置非常快速的
    isset()
    检查
    isset()
    可能会优于
    array\u key\u exists()
    ,因为
    isset()
    不检查
    null
  • 我正在将
    FILE\u SKIP\u EMPTY\u line
    标记添加到
    FILE()
    调用中,以便查找数组可能更小
  • 对大文件的每一行调用
    rtrim()
    ,也可能会造成一些阻力。您知道两个文件上的换行符是否一致吗?如果您可以安全地从
    文件()调用中删除
    文件
    忽略
    新行
    标志,那么您将节省六亿次调用
    rtrim()。或者,如果您知道跟踪big.txt行的换行符(例如,
    \n
    ?或
    \r\n
    ?),则可以将特定换行符附加到
    $lookup
    键中——这意味着相对于大文件的每一行,准备较小文件的数据
  • 未测试代码:

    $lookup = array_flip(file('small.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    if($file = fopen('big.txt', 'r')){
        while(!feof($file)){
            $line = rtrim(fgets($file));
            if (isset($lookup[$line])) {
                echo "$lines : exists.\n";
            }
        }
        fclose($file);
    }
    

    快速不是PHP的特性之一。也许您可以通过不在数组()中使用
    ,而使用
    $wordlist=array\u flip($wordlist)
    将单词列表元素转换为数组键,然后使用
    isset()
    检查字符串是否在列表中来加快速度。这应该利用密钥散列来加快速度。您正在执行
    echo$行。“:exists。\n”表示您正在输出结果。最好将这些行存储在数组中,或者存储行号,然后处理数据。第二:如果这个小列表是一本字典,那么你需要确保它们被排序。如果这是真的。。。然后,我将编写自己的函数,以根据第一个字母进行比较。在您的例子中,从大文件中取出一行,然后遍历2M行。我会找到一种方法来优化这个。。。您真的需要遍历所有这些行吗?如果您使用带有固定大小缓冲区的C,它将以您的硬盘读取文件的速度运行。@jdigital这一直是计划
    isset()
    做了同样的事情,可能更快,因为它不是真正的函数
    array\u key\u exists()
    不通过引用获取参数,这意味着复制字符串和更多延迟。
    small.txt
    很小,只在程序开始时读取一次,无论您解析此文件的方式有多大的性能差异,都不会影响程序的整体性能。但是,请尝试考虑每个本机函数的内部函数。首先
    文件
    与我收集所有行的方法相同,然后
    array\u filter
    再次循环过滤空字符串,在
    array unique
    之后,实现复制和循环查找唯一值,最后
    array\u flip
    也循环通过数组。想想我们所说的时间复杂度和内存使用情况……你可以根据自己的意愿对其进行否决,但PHP是一种高级语言,如果你真的知道C是如何工作的,你就会明白,或者这无关紧要。。。我只使用一个本机函数fopen来实现它…@Havenard你所说的small是指一个数组中有2百万行,因此有大约2百万个条目。你能自己尝试实现所有这些本机函数,并仔细考虑这行的全局时间复杂度和内存使用情况吗?$wordlist=array\u flip(array\u unique)(array\u filter(file('small.txt',FILE_IGNORE_NEW_line)))`……完成后请告诉我。这与PHP循环和过程不同,因为这些函数在内部用本机代码编写,所以性能永远不会匹配。正如您所说,这些函数在内部是用C编写的,逻辑在C和PHP中是相同的。算法效率的判断与lan无关基于时间复杂度和内存使用情况的语言。根据你的建议,你的建议使用的内存比我的建议少…而且如果你只使用了这些功能中的一个,你的演讲将是可以接受的,但4。。。