2014-04-05 2 views
1

매우 큰 파일을 사용하는 데 문제가 있습니다. 나는 여러 부분으로 파일을 나누어서 해결책을 만들려고 노력했다. 그러나 문제는 큰 파일이기 때문에 여전히 거기에 있습니다. 이 같은 그림 :파싱 및 대용량 파일에서 값 가져 오기

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 
} 

큰 데이터로 인해 문제가 여전히 남아 있습니다. 대부분의 데이터를 200KB로 삭제하려고 시도했지만 해결 된 솔루션입니다. 그러나 그것은 데이터가 불완전하기 때문에 내가 원하는 것이 아닙니다. 이 문제를 해결할 수있는 다른 해결책이 있습니까? 여부를 일으킬 수없는 file_get_contents의 사용으로 인해 여부? 매우 큰 파일의 값을 검색하는 다른 방법이 있습니까?

[UPDATE]

<?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; 
       } 

      } 
} 
?> 

설명 : 이 경우는, 위치 데이터는 이미 정렬되어있다. 코드에서 "if($data2[$j][1] == $posi[$i] && $data2[$j][3] == $ref[$i] && $data2[$j][4] == $alt[$i])"이 true 일 때 파일을 풀어서 루프 "for $j"에서 벗어났습니다. 그런 다음 루프 (for $i)의 시작 부분까지 파일 선택 (스위치) 및 "if($data2[$j][1] == $posi[$i] && $data2[$j][3] == $ref[$i] && $data2[$j][4] == $alt[$i])" 등을 수행합니다. 그래서, 모든 파일을 읽지는 않습니다, 그냥 위치를 찾을 때까지 파일을 읽었습니다.

하지만 파일을 여는 방법을 모르겠습니다. 위의 코드를 수행하면 너무 큰 파일에서 항상 실패합니다.

+0

이 한 번에 모든 데이터를해야합니까 ? 대신 라인을 한 줄씩 읽을 수 있습니까? 오래된 라인을 메모리에서 제거하면됩니까? –

+0

나는 그것이 실제로 그것을 원했다. 나는 나의 포스트를 더 명확하게 편집했다. 나 좀 도와 줄 수있어? – user3193610

+0

코드 오류가있는 것 같습니다. 당신이하고있는 것은 :'$ data2 = array();''$ data2'에 기초한 루핑입니다. 항상 비어있게됩니다. –

답변

1

또한 당신이 1GB의 경우에도, 단지 1 개 개의 파일로 동일한 기능을 수행 할 수있는 선으로 독서 라인을 수행 (단지 오래 걸립니다) :

<?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); 
    }   
} 
+0

alhamdulillah. 덕분에 내 친구. 좋아. – user3193610

관련 문제