Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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_File - Fatal编程技术网

在PHP中读取文件的内存占用最少的方法

在PHP中读取文件的内存占用最少的方法,php,file,Php,File,我正在使用Php中的file()函数读取一个包含大约50k行的文件。但是,由于文件内容以数组形式存储在内存中,因此会出现内存不足错误。还有别的办法吗 此外,存储的行的长度是可变的 这是密码。此外,该文件是700kB而不是mB private static function readScoreFile($scoreFile) { $file = file($scoreFile); $relations = array(); for($i = 1; $i < coun

我正在使用Php中的file()函数读取一个包含大约50k行的文件。但是,由于文件内容以数组形式存储在内存中,因此会出现内存不足错误。还有别的办法吗

此外,存储的行的长度是可变的

这是密码。此外,该文件是700kB而不是mB

private static function readScoreFile($scoreFile)
{
    $file = file($scoreFile);
    $relations = array();

    for($i = 1; $i < count($file); $i++)
    {
        $relation = explode("\t",trim($file[$i]));
        $relation = array(
                        'pwId_1' => $relation[0],
                        'pwId_2' => $relation[1],
                        'score' => $relation[2],
                        );
        if($relation['score'] > 0)
        {
            $relations[] = $relation;
        }
    }

    unset($file);
    return $relations;
}
私有静态函数readScoreFile($scoreFile)
{
$file=file($scoreFile);
$relations=array();
对于($i=1;$i$relationship[0],
'pwId_2'=>$relationship[1],
“分数”=>$relationship[2],
);
如果($relation['score']>0)
{
$relations[]=$relations;
}
}
未设置($文件);
返回美元关系;
}
使用和按顺序读取文件:

$handle = fopen($filename, 'r');
if ($handle) {
    while (!feof($handle)) {
        echo fread($handle, 8192);
    }
    fclose($handle);
}

更新问题后编辑,并:

若一个700kb的文件用您提供的代码占用了140MB的内存,那个么肯定会有些可疑(不过,您可以在每次迭代结束时
取消设置
$关系)。考虑使用调试器来检查它,看看会发生什么。您可能还需要考虑改写代码来使用()


要使用OOP方法迭代文件,请尝试:

甚至

foreach(new SplFileObject("misc.txt") as $line) {
    echo $line;
}
非常相关(如果不重复):


在操作过程中分配更多内存,可能类似ini_set(“内存限制”、“16M”);。操作完成后,不要忘记返回初始内存分配

如果您不知道最大行长,并且不习惯使用幻数作为最大行长,则需要对文件进行初始扫描并确定最大行长

除此之外,以下代码应该可以帮助您:

    // length is a large number or calculated from an initial file scan
    while (!feof($handle)) {
        $buffer = fgets($handle, $length);
        echo $buffer;
    }

这是一个老问题,但因为我没见过有人提到它,这是一个减少内存消耗的好方法

例如:

function read($fileName)
{
    $fileHandler = fopen($fileName, 'rb');

    while(($line = fgets($fileHandler)) !== false) {
        yield rtrim($line, "\r\n");
    }

    fclose($fileHandler);
}

foreach(read(__DIR__ . '/filenameHere') as $line) {
    echo $line;
}

我认为这仍然可能会占用一大块内存,因为我认为它会继续读取,直到找到行尾为止。@a事实上,如果这是一个问题,您仍然可以使用
SplFileObject::setMaxLineLen
。@Gordon Right。我认为我对SplFileObject的熟悉程度可以提高:p@Gordon那为什么不去弗雷奇呢
foreach(新的SplFileObject(“misc.txt”)作为$line){…}
@artifact,因为我是在懒洋洋地复制PHP手册中的示例;)这行不通,我想逐行读。它在每个fread上返回的多行(我猜是8192字节)将fread替换为“fgets”:fgets-从文件点获取行您可以使用中间变量$line来存储每行的字节,然后回显$line。fread可能是流式处理文件的最有效方法之一,因此请阅读fread的结果(并附加到$line),直到找到换行符。然后对该行执行任何操作,然后设置$line=“”,并继续将fread的结果附加到$line。问题是,行的长度是可变的。因此,在某些地方,我得到了大约一半的行。由于文件中的行长度不同,使用fread不是一个好方法。我非常确定,在操作后,您不必重置内存限制,它只适用于当前运行的脚本。我已经使用了140MB的内存(读文件的过程中有很多东西)@Chetan这听起来很可疑。50k行并没有那么多。它有大约20k行,是1MB的纯文本,当用文件()读入时只占用大约3MB。文件的总大小(字节)是多少?@Gordon该文件大约为700 MB,但它是一个TSV文件,读取该文件后,我将每行拆分并存储到一个数组中。因此,这就像一个30k X 5的数组,这就是它占用如此多内存的原因guess@Chetan您确定没有在某处泄漏内存吗?请尝试取消设置未使用的内存变量,尤其是循环时。也许你可以发布一些代码让我们看看。我知道这个问题很老,但这里有两件事。1.逐行读取文件。2.内存不足的错误可能是你也在数组中存储所有内容,如果没有某种控制和内存知识,这通常不是一个好主意
foreach(new SplFileObject("misc.txt") as $line) {
    echo $line;
}
    // length is a large number or calculated from an initial file scan
    while (!feof($handle)) {
        $buffer = fgets($handle, $length);
        echo $buffer;
    }
function read($fileName)
{
    $fileHandler = fopen($fileName, 'rb');

    while(($line = fgets($fileHandler)) !== false) {
        yield rtrim($line, "\r\n");
    }

    fclose($fileHandler);
}

foreach(read(__DIR__ . '/filenameHere') as $line) {
    echo $line;
}