【问题标题】:Remove lines from updating csv file从更新 csv 文件中删除行
【发布时间】:2015-09-27 22:58:38
【问题描述】:

在我的 wamp 服务器中,我有一个每秒更新 csv 文件的脚本。 我想从 csv 文件中删除行,我有这段代码(来自这里:How To Delete The Top 100 Rows From a CSV File With PHP):

$input = explode("\n", file_get_contents("file.csv"));
foreach ($input as $line) {
 // process all lines.
}

// This function removes first 100 elements.
// More info:
// http://php.net/manual/en/function.array-slice.php
$output = array_slice($input, 100);
file_put_contents("out.csv", implode("\n", $output));

当我尝试运行上面的代码时发生了问题,我得到:

“未能打开流权限被拒绝”

问题是因为文件一直在更新。 我怎么知道? 我做了一个 csv 的副本(这个文件的内容根本没有更新),它是成功的。

为什么我需要这个?

因为文件正在增长,我必须从他那里删除行..如果我不这样做,我会得到:“PHP 致命错误:允许的 ******** 字节的内存大小已用尽(试图分配71 个字节)在 /var/www/*******.php 第 54 行,”即使我写了 ini_set("memory_limit", "-1");

我提醒你 - 这是 wamp 服务器!

有什么想法吗?

谢谢!

【问题讨论】:

  • 你为什么要每秒写入一个 csv?
  • 一些重要数据。因为文件正在增长,我必须从他那里删除行..如果我不这样做,我会得到:“PHP 致命错误:允许的 ******** 字节的内存大小已用尽(尝试分配 71 个字节)在 /var/www/*******.php 第 578 行,”即使我写了 ini_set("memory_limit", "-1");
  • 你不能编辑更新文件的脚本并删除那里多余的行吗?

标签: php wamp fgetcsv fputcsv php-5.6


【解决方案1】:

这不是你问的。但在我看来,你现有的方案是错误的。然后你正在寻找一个愚蠢的解决方案来修复它。您有多任务问题,这不是一个快速的过程。每次执行此操作时,您也可能会丢失几行。

执行此操作的正确方法是创建一个文件夹,说 LOGS

然后放入一个名为 YYYYMMDD.CSV 的文件。每天换个名字。并删除任何超过 7 天的内容。

【讨论】:

    【解决方案2】:
    $input = explode("\n", file_get_contents("file.csv"));
    foreach ($input as $line) {
     // process all lines.
    }
    
    // This function removes first 100 elements.
    // More info:
    // http://php.net/manual/en/function.array-slice.php
    $output = array_slice($input, 100);
    file_put_contents("out.csv", implode("\n", $output));
    

    当我尝试运行上面的代码时发生了问题,我得到:

    “未能打开流权限被拒绝”

    这里有 3 种情况你不能修改文件。

    1. 文件已在使用中(被另一个进程锁定)。
    2. 文件没有正确的权限 (R/W)。或者文件不属于您正在使用的用户/组,在必须的 php 情况下它是 (www-data)。
    3. 文件不存在。

    1) 如果文件已在使用中,则无法修改,但可以尝试其他方法 * A RACE CONDITION * 可以实现:

    # RACE CONDITION LOOP
    # The only way you have here is to setup a RC loop to check if/when the file can be written.
    $Path   = dirname ( __FILE__ ) . "path_to_your_file/out.csv";
    $tries  = 99; // Any number of tries you want.
    for ( $i = 1; $i < $tries; $i++ )
    {
        $output = array_slice ( $input, 100 );
        {
            if ( @file_put_contents ( $Path , implode ( "\n", $output ) ) )
            {
                echo "Content Added!"."<br>";
                $i = $tries;
            }
            else
            {
                echo "Content Cannot be Added!"."<br>";
            }
        }
    
        ob_flush ( );
        echo "We Have tried " . $i . " times to add content to the file"."<br>";
        sleep ( 1 );
        flush ( );
    }
    

    2) 如果 File 没有正确的权限,您可以在代码中设置它:

    $Path   = dirname ( __FILE__ ) . "path_to_your_file/out.csv";
    $Mode   = 0755; // permissions wanted
    $Umsk   = @umask( 0 );
    @chmod ( $Path, $Mode );
    @umask ( $Umsk );
    

    3) 如果文件不存在,您可以创建它,但首先要确保检查它是否存在:

    # Make sure the file that contain this code have the right permissions, user/group .
    # If not this cannot create the file and will not allow you execute the whole code .
    $Path   = dirname ( __FILE__ ) . "path_to_your_file/out.csv";
    $Mode   = 0755; // permissions wanted
    $Check_File = file_exists ( $Path );
    if ( $Check_File ) { $File_Exist = true; }
    else { $File_Exist = false; }
    
    if ( $File_Exist )
    {
        @touch ( $Path );
        @chmod ( $Path, $Mode );
    }
    else
    {
        echo "File Already Exist";
    }
    

    我希望这会有所帮助,如果没有,请具体说明问题所在。

    PS:对于内存限制错误,一些服务器和/或主机提供商不允许在用户的 php.ini 或从 php 中设置此内容。您必须编辑 php 和 apache 的全局配置文件,如果您正在为数据库使用大量数据,可能还需要编辑 mysql,以允许最大选择的内存限制值。

    【讨论】:

      猜你喜欢
      • 2018-08-15
      • 2011-05-03
      • 2020-07-18
      • 1970-01-01
      • 2018-07-29
      • 2020-12-17
      • 2020-09-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多