从大文件php解析并获取值
我对使用非常大的文件有一个问题。我试图通过将文件分成几个部分来解决问题。但问题仍然存在,因为它是一个大文件。 如下图所示:从大文件php解析并获取值,php,file-get-contents,large-files,Php,File Get Contents,Large Files,我对使用非常大的文件有一个问题。我试图通过将文件分成几个部分来解决问题。但问题仍然存在,因为它是一个大文件。 如下图所示: A = 1GB file; I broke into file A_1 = 200MB, file A_2 = 200MB, and so on. 我的逻辑是,如果我使用一个文件(A),那么我会: for ( ... ) { $data = file_get_contents("data/A.vcf"); //code that is very complex
A = 1GB file;
I broke into
file A_1 = 200MB, file A_2 = 200MB, and so on.
我的逻辑是,如果我使用一个文件(A),那么我会:
for ( ... )
{
$data = file_get_contents("data/A.vcf");
//code that is very complex (including parsing the data) related to the contents of the data and I will often use file_get_contents due to looping
}
然后,我使用文件的值/位置将逻辑更改为几个部分,即:
for ( ... )
{
switch($position)
{
case(($position >= 0) && ($position < 5000000)):
$data = file_get_contents("data/A_1.vcf");
break;
case(($position >= 5000000) && ($position < 10000000)):
$data = file_get_contents("data/A_2.vcf");
break;
case(($position >= 10000000) && ($position < 20000000)):
$data = file_get_contents("data/A_3.vcf");
break;
case(($position >= 20000000) && ($position < 30000000)):
$data = file_get_contents("data/A_4.vcf");
break;
...
}
//code that is very complex ( including parsing the data ) related to the contents of the data and I will often use file_get_contents due to looping
}
(…)的
{
开关($位置)
{
案例(($position>=0)和($position<5000000)):
$data=文件获取内容(“data/A_1.vcf”);
打破
案例(($position>=5000000)和($position<10000000)):
$data=文件获取内容(“data/A_2.vcf”);
打破
案例(($position>=10000000)和($position<20000000)):
$data=文件获取内容(“data/A_3.vcf”);
打破
案例(($position>=20000000)和($position<30000000)):
$data=文件获取内容(“data/A_4.vcf”);
打破
...
}
//与数据内容相关的代码非常复杂(包括解析数据),由于循环,我经常使用file\u get\u内容
}
但问题仍然存在,因为数据量很大。我已经尝试将大部分数据删除到200KB,解决方案已经解决。但这不是我想要的,因为数据不完整。
有没有其他解决办法?是否由于使用文件\u获取\u内容而导致它无法访问?有没有其他方法可以检索非常大的文件的值
[更新]
说明:
在这种情况下,位置数据已经排序。在代码中,当“如果($data2[$j][1]=$posi[$I]&$data2[$j][3]=$ref[$I]&&$data2[$j][4]=$alt[$I])”
为true时,我需要它,然后文件被释放并退出循环“for$j”
。然后一直到循环的开头,执行文件选择(切换),如果($data2[$j][1]=$posi[$i]&&$data2[$j][3]=$ref[$i]&$data2[$j][4]==$alt[$i]),等等。
所以,我不读取所有文件,我只是在找到位置之前读取文件
但我不知道如何释放文件。如果我这样做,上述代码在太大的文件上总是失败。逐行读取,也可以只读取一个文件,即使它是1 GB(只需要更长的时间):
您必须同时拥有所有数据吗?你能一行一行地读它吗,一边读一边从记忆中释放旧的行?我真的很喜欢它。我已经编辑了我的帖子。你能帮我吗?好像有个密码错误。您正在执行:$data2=array()
然后基于始终为空的$data2
循环。否,$data2用于分隔“\t”。我想问,如何释放文件?所以,我不阅读所有的文件,我只是在找到位置之前阅读文件。查看我添加的答案。您可以使用fgets
逐行读取。
<?php
/*
I take random data from multiple large files to try
50001374 rs389045667 T C
10000685 rs123308931 A C
39769437 rs393441165 C T
26907032 rs393470108 C T
50001195 rs122244329 G T
*/
$posi = array(50001374,10000685,39769437, 26907032, 50001195);
$id = array(".",".",".",".",".");
$ref = array("T","A","C","C","G");
$alt = array("C","C","T","T","T");
for($i=0; $i<5; $i++)
{
switch($posi[$i])
{
case (($posi[$i] >= 0 ) && ($posi[$i] < 5000000 )):
$data = file_get_contents("data/ncbi/5.vcf");
break;
case (($posi[$i] >= 5000000 ) && ($posi[$i] < 10000000 )):
$data = file_get_contents("data/ncbi/10.vcf");
break;
case (($posi[$i] >= 10000000 ) && ($posi[$i] < 20000000 )):
$data = file_get_contents("data/ncbi/20.vcf");
break;
case (($posi[$i] >= 20000000 ) && ($posi[$i] < 30000000 )):
$data = file_get_contents("data/ncbi/30.vcf");
break;
case (($posi[$i][2] >= 30000000 ) && ($posi[$i] < 40000000 )):
$data = file_get_contents("data/ncbi/40.vcf");
break;
case (($posi[$i] >= 40000000 ) && ($posi[$i] < 50000000 )):
$data = file_get_contents("data/ncbi/50.vcf");
break;
case ($posi[$i] >= 50000000 ):
$data = file_get_contents("data/ncbi/60.vcf");
break;
}
$data = explode("\n", $data);
$data2=array();
foreach ($data2 as $dat)
{
$data2[] = explode("\t", $dat);
}
for($j = 0 ; $j < count($data2); $j++)
{
if($data2[$j][1] == $posi[$i] && $data2[$j][3] == $ref[$i] && $data2[$j][4] == $alt[$i])
{
echo '<pre>';
print_r($posi[$i]. "\n");
print_r($id[$i]. "\n");
print_r($ref[$i]. "\n");
print_r($alt[$i]. "\n");
echo '</pre>';
break;
}
}
}
?>
<?php
/*
I take random data from multiple large files to try
50001374 rs389045667 T C
10000685 rs123308931 A C
39769437 rs393441165 C T
26907032 rs393470108 C T
50001195 rs122244329 G T
*/
$posi = array(50001374,10000685,39769437, 26907032, 50001195);
$id = array(".",".",".",".",".");
$ref = array("T","A","C","C","G");
$alt = array("C","C","T","T","T");
for($i=0; $i<5; $i++)
{
switch($posi[$i])
{
case (($posi[$i] >= 0 ) && ($posi[$i] < 5000000 )):
$file = "data/ncbi/5.vcf";
break;
case (($posi[$i] >= 5000000 ) && ($posi[$i] < 10000000 )):
$file = "data/ncbi/10.vcf";
break;
case (($posi[$i] >= 10000000 ) && ($posi[$i] < 20000000 )):
$file = "data/ncbi/20.vcf";
break;
case (($posi[$i] >= 20000000 ) && ($posi[$i] < 30000000 )):
$file = "data/ncbi/30.vcf";
break;
case (($posi[$i][2] >= 30000000 ) && ($posi[$i] < 40000000 )):
$file = "data/ncbi/40.vcf";
break;
case (($posi[$i] >= 40000000 ) && ($posi[$i] < 50000000 )):
$file = "data/ncbi/50.vcf";
break;
case ($posi[$i] >= 50000000 ):
$file = "data/ncbi/60.vcf";
break;
}
$handle = fopen($file, "r");
if ($handle) {
while (($line = fgets($handle, 4096)) !== false) {
$line = explode("\t", $line);
if($line[1] == $posi[$i] && $line[3] == $ref[$i] && $line[4] == $alt[$i]) {
echo '<pre>';
print_r($posi[$i]. "\n");
print_r($id[$i]. "\n");
print_r($ref[$i]. "\n");
print_r($alt[$i]. "\n");
echo '</pre>';
break;
}
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}
}