【问题标题】:PHP: Read Specific Line From FilePHP:从文件中读取特定行
【发布时间】:2011-08-12 03:20:13
【问题描述】:

我正在尝试使用 php 从文本文件中读取特定行。 这是文本文件:

foo  
foo2

如何使用 php 获取第二行的内容? 这将返回第一行:

<?php 
$myFile = "4-24-11.txt";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
?>

..但我需要第二个。

任何帮助将不胜感激

【问题讨论】:

    标签: php file line


    【解决方案1】:
    $myFile = "4-24-11.txt";
    $lines = file($myFile);//file in to an array
    echo $lines[1]; //line 2
    

    file — Reads entire file into an array

    【讨论】:

    • 注意:应该是$lines[1]
    • 谢谢你!这正是我所需要的!另外,感谢您这么快回答。
    • 如果文件很大,这个解决方案会很慢并且占用大量内存。
    • 还有 40 多张赞成票?我会说这还不算太糟糕;-)
    • 将整个文件读入内存只是为了得到第二行?我会说这在某些情况下会导致灾难(请参阅 Raptor 的评论)。
    【解决方案2】:

    omg 我缺少 7 个代表来制作 cmets。这是@Raptor 和@Tomm 的评论,因为这个问题在 google serps 中仍然很高。

    他完全正确。对于小文件file($file); 非常好。对于大文件来说,b/c php 数组会像疯了一样吃掉内存。

    我刚刚使用文件大小约为 67mb(1,000,000 行)的 *.csv 运行了一个小测试:

    $t = -microtime(1);
    $file = '../data/1000k.csv';
    $lines = file($file);
    echo $lines[999999]
        ."\n".(memory_get_peak_usage(1)/1024/1024)
        ."\n".($t+microtime(1));
    //227.5
    //0.22701287269592
    //Process finished with exit code 0
    

    因为还没有人提到它,所以我尝试了SplFileObject,实际上是我最近才为自己发现的。

    $t = -microtime(1);
    $file = '../data/1000k.csv';
    $spl = new SplFileObject($file);
    $spl->seek(999999);
    echo $spl->current()
        ."\n".(memory_get_peak_usage(1)/1024/1024)
        ."\n".($t+microtime(1));
    //0.5
    //0.11500692367554
    //Process finished with exit code 0
    

    这是在我的 Win7 桌面上,所以它不代表生产环境,但仍然......非常不同。

    【讨论】:

    • 对于一个迟到的问题的答案很好,而且很有帮助。 +1
    • 请记住SplFileObject 会锁定文件。因此,当不再需要类时,将其设为空(例如$spl = null;),否则您将被拒绝对该文件执行一些其他操作 - 删除、重命名、在类外访问等。
    【解决方案3】:

    如果你想那样做......

    $line = 0;
    
    while (($buffer = fgets($fh)) !== FALSE) {
       if ($line == 1) {
           // This is the second line.
           break;
       }   
       $line++;
    }
    

    或者,使用file() 打开它并使用[1] 为该行下标。

    【讨论】:

    • 所以基本上,将它输入一个数组并取出第二个项目。我知道了。谢谢。
    • @Sang 第一个解决方案刚刚给出了适合您现在的代码的解决方案。
    【解决方案4】:

    我会使用 SplFileObject 类...

    $file = new SplFileObject("filename");
    if (!$file->eof()) {
         $file->seek($lineNumber);
         $contents = $file->current(); // $contents would hold the data from line x
    }
    

    【讨论】:

    • #Salute #Revoutionary 很棒的方法:)
    【解决方案5】:

    您可以使用以下内容获取文件中的所有行

    $handle = @fopen('test.txt', "r");
    
    if ($handle) { 
       while (!feof($handle)) { 
           $lines[] = fgets($handle, 4096); 
       } 
       fclose($handle); 
    } 
    
    
    print_r($lines);
    

    $lines[1] 你的第二行

    【讨论】:

    • 谢谢兄弟!感谢您的回答。
    【解决方案6】:
    $myFile = "4-21-11.txt";
    $fh = fopen($myFile, 'r');
    while(!feof($fh))
    {
        $data[] = fgets($fh);  
        //Do whatever you want with the data in here
        //This feeds the file into an array line by line
    }
    fclose($fh);
    

    【讨论】:

    • 啊。我知道了。谢谢回答。 :)
    • 顺便说一句,如果您可能使用任何大文件,则在实践中不建议将整个文件放入数组中,例如使用file()file_get_contents()。对于小文件,效果很好。
    【解决方案7】:

    这个问题现在已经很老了,但对于任何处理非常大文件的人来说,这里是一个不涉及读取每一行的解决方案。这也是对我来说只有约 1.6 亿行文件有效的解决方案。

    <?php
    function rand_line($fileName) {
        do{
            $fileSize=filesize($fileName);
            $fp = fopen($fileName, 'r');
            fseek($fp, rand(0, $fileSize));
            $data = fread($fp, 4096);  // assumes lines are < 4096 characters
            fclose($fp);
            $a = explode("\n",$data);
        }while(count($a)<2);
        return $a[1];
    }
    
    echo rand_line("file.txt");  // change file name
    ?>
    

    它的工作原理是在不读取任何内容的情况下打开文件,然后立即将指针移动到随机位置,从该点读取多达 4096 个字符,然后从该数据中获取第一行完整的行。

    【讨论】:

      【解决方案8】:

      如果您在 Linux 上使用 PHP,您可以尝试以下方法来读取例如第 74 行到第 159 行之间的文本:

      $text = shell_exec("sed -n '74,159p' path/to/file.log");
      

      如果你的文件很大,这个解决方案很好。

      【讨论】:

      • 虽然此解决方案在您知道将要部署的位置时有效,但在您不了解目标系统的情况下它并不是最佳选择。
      【解决方案9】:

      你必须循环文件直到文件结束。

        while(!feof($file))
        {
           echo fgets($file). "<br />";
        }
        fclose($file);
      

      【讨论】:

        【解决方案10】:

        使用stream_get_line:stream_get_line — 从流资源中获取到给定分隔符的行 来源:http://php.net/manual/en/function.stream-get-line.php

        【讨论】:

          【解决方案11】:

          您可以尝试循环直到您想要的行,而不是 EOF,并且每次都将变量重置到该行(而不是添加到它)。在您的情况下,第二行是 EOF。 (在我下面的代码中,for 循环可能更合适)。

          这样整个文件不在内存中;缺点是需要时间才能将文件浏览到您想要的位置。

          <?php 
          $myFile = "4-24-11.txt";
          $fh = fopen($myFile, 'r');
          $i = 0;
          while ($i < 2)
           {
            $theData = fgets($fh);
            $i++
           }
          fclose($fh);
          echo $theData;
          ?>
          

          【讨论】:

            【解决方案12】:

            我喜欢daggett answer,但是如果您的文件不够大,您可以尝试另一种解决方案。

            $file = __FILE__; // Let's take the current file just as an example.
            
            $start_line = __LINE__ -1; // The same with the line what we look for. Take the line number where $line variable is declared as the start.
            
            $lines_to_display = 5; // The number of lines to display. Displays only the $start_line if set to 1. If $lines_to_display argument is omitted displays all lines starting from the $start_line.
            
            echo implode('', array_slice(file($file), $start_line, lines_to_display));
            

            【讨论】:

              【解决方案13】:

              我搜索了一种从文件中读取特定行的单行解决方案。 这是我的解决方案:

              echo file('dayInt.txt')[1]

              【讨论】:

                猜你喜欢
                • 2013-08-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多