2010-01-11 7 views
1

PHP를 사용하여 큰 텍스트 파일을 문자 수로 나누면 어떻게 될까요? 1000 문자마다 10,000 개의 문자 파일을 분할하면 10 개의 파일로 분할됩니다. 또한, 전체 중지가 발견 된 후에 만 ​​분할 할 수 있습니까?PHP로 텍스트 파일 분할하기

감사합니다.

업데이트 1 : zombats 코드가 마음에 들었고 몇 가지 오류를 제거하고 다음을 생각해 냈지만 아무도 완전히 멈춘 후에 만 ​​나누는 방법을 알고 있습니까?

$i = 1; 
    $fp = fopen("test.txt", "r"); 
    while(! feof($fp)) { 
     $contents = fread($fp,1000); 
     file_put_contents('new_file_'.$i.'.txt', $contents); 
     $i++; 
    } 

업데이트 2 : 나는 zombats 제안했다 아래 것과 코드를 수정하고 그것을 작동하는 것 같다 -

$i = 1; 
    $fp = fopen("test.txt", "r"); 
    while(! feof($fp)) { 
     $contents = fread($fp,20000); 
     $contents .= stream_get_line($fp,1000,"."); 
     $contents .="."; 

     file_put_contents("Split/".$tname."/"."new_file_".$i.".txt", $contents); 
     $i++; 
    } 

답변

2

당신은 기본 fread() 쉽게이 작업을 수행 할 수 있어야합니다. 읽을 바이트 수를 지정할 수 있으므로 정확한 양으로 읽고 새 파일로 출력하는 것은 간단합니다. 이 같은

시도 뭔가 :

$i = 1; 
$fp = fopen("test.txt",'r'); 
while(! feof($fp)) { 
    $contents = fread($fp,1000); 
    file_put_contents('new_file_'.$i.'.txt',$contents); 
    $i++; 
} 

EDIT 당신이 특정 문자에 길이 또는의 일정 금액 후 중지하고자하는 경우, 당신은 stream_get_line()를 사용하는 대신 fread()

. 그것은 당신이 원하는 엔딩 구분 기호를 지정할 수 있다는 것을 제외하면 거의 동일합니다. 이 아님을 유의하십시오.은 판독기의 일부로 delimeter를 반환합니다.

$contents = stream_get_line($fp,1000,"."); 
+0

감사합니다. 그러나 완전히 멈춘 후에 만 ​​분할 할 수 있습니까? – usertest

+0

업데이트 된 답변보기 – zombat

+0

나는 길이 대신 20000을 사용하여 stream_get_line을 시도했고 gutenberg 사이트의 큰 텍스트 파일 중 하나 인 http://www.gutenberg.org/files/2759/2759.txt를 사용했습니다. 텍스트가 거의없는 1,000 개가 넘는 파일이 생성되었습니다. – usertest

1

가장 쉬운 방법은 파일의 내용을 읽을 수있다, 내용을 분할 그런 다음 두 개의 다른 파일에 저장하십시오. 파일이 몇 기가 바이트 이상이면 정수 크기 제한으로 인해 PHP에서 문제가 발생할 수 있습니다.

+0

, 단순히 루프에서 필요한 바이트 수를 읽어보다는 한 번에 전체 원본 파일에 읽기 훨씬 더 효율적이 될 것입니다. 정수 최대 값보다 큰 파일 청크를 읽지 않는 한 크기 문제가 발생하지 않습니다. – zombat

+0

좀 더 자세히 설명 했어야하는데, 텍스트 파일의 크기는 10-15MB가 넘지 않을 것입니다. – usertest

+0

@ zombat, PHP는 파일 읽기 포인터를 4,294,967,296 바이트 넘게 만들 수 없습니다. 파일이 4GB 이상인 경우, 청크로 읽더라도 PHP가 4GB 표시에 도달하면 PHP가 쓰레기를 버립니다. – Ian

1

이 작업을 수행하는 클래스를 작성할 수도 있습니다.

<?php 

/** 
* filesplit class : Split big text files in multiple files 
* 
* @package 
* @author Ben Yacoub Hatem <[email protected]> 
* @copyright Copyright (c) 2004 
* @version $Id$ - 29/05/2004 09:02:10 - filesplit.class.php 
* @access public 
**/ 
class filesplit{ 
    /** 
    * Constructor 
    * @access protected 
    */ 
    function filesplit(){ 

    } 

    /** 
    * File to split 
    * @access private 
    * @var string 
    **/ 
    var $_source = 'logs.txt'; 

    /** 
    * 
    * @access public 
    * @return string 
    **/ 
    function Getsource(){ 
     return $this->_source; 
    } 

    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function Setsource($newValue){ 
     $this->_source = $newValue; 
    } 

    /** 
    * how much lines per file 
    * @access private 
    * @var integer 
    **/ 
    var $_lines = 1000; 

    /** 
    * 
    * @access public 
    * @return integer 
    **/ 
    function Getlines(){ 
     return $this->_lines; 
    } 

    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function Setlines($newValue){ 
     $this->_lines = $newValue; 
    } 

    /** 
    * Folder to create splitted files with trail slash at end 
    * @access private 
    * @var string 
    **/ 
    var $_path = 'logs/'; 

    /** 
    * 
    * @access public 
    * @return string 
    **/ 
    function Getpath(){ 
     return $this->_path; 
    } 

    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function Setpath($newValue){ 
     $this->_path = $newValue; 
    } 

    /** 
    * Configure the class 
    * @access public 
    * @return void 
    **/ 
    function configure($source = "",$path = "",$lines = ""){ 
     if ($source != "") { 
      $this->Setsource($source); 
     } 
     if ($path!="") { 
      $this->Setpath($path); 
     } 
     if ($lines!="") { 
      $this->Setlines($lines); 
     } 
    } 


    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function run(){ 
     $i=0; 
     $j=1; 
     $date = date("m-d-y"); 
     unset($buffer); 

     $handle = @fopen ($this->Getsource(), "r"); 
     while (!feof ($handle)) { 
      $buffer .= @fgets($handle, 4096); 
      $i++; 
       if ($i >= $split) { 
       $fname = $this->Getpath()."part.$date.$j.txt"; 
       if (!$fhandle = @fopen($fname, 'w')) { 
        print "Cannot open file ($fname)"; 
        exit; 
       } 

       if ([email protected]($fhandle, $buffer)) { 
        print "Cannot write to file ($fname)"; 
        exit; 
       } 
       fclose($fhandle); 
       $j++; 
       unset($buffer,$i); 
       } 
     } 
     fclose ($handle); 
    } 


} 
?> 


Usage Example 
<?php 
/** 
* Sample usage of the filesplit class 
* 
* @package filesplit 
* @author Ben Yacoub Hatem <[email protected]> 
* @copyright Copyright (c) 2004 
* @version $Id$ - 29/05/2004 09:14:06 - usage.php 
* @access public 
**/ 

require_once("filesplit.class.php"); 

$s = new filesplit; 

/* 
$s->Setsource("logs.txt"); 
$s->Setpath("logs/"); 
$s->Setlines(100); //number of lines that each new file will have after the split. 
*/ 

$s->configure("logs.txt", "logs/", 2000); 
$s->run(); 
?> 

소스 http://www.weberdev.com/get_example-3894.html

+0

이것은 정확히 내가 필요로하는, 매우 유용하지만, 문제가있다. 내가 무엇을 설정했는지에 상관없이, 그것은 내 소스 파일의 각 줄을 별도의 파일에 넣는다. 그래서 500 라인 파일 500 파일을 만듭니다 – JasonDavis

+0

내 대답은 아래의 수정 된 코드를 참조하십시오. run() 함수에서 편집을하면 이제 제대로 작동합니다. 죄송합니다. 4 년 후이 페이지를 방문한 사람에게 도움이되기를 바랍니다. –

4

실행 기능에 버그가 있습니다. 변수 $split이 정의되지 않았습니다.

0

run 함수에서 "split is not defined"경고를 수정하기 위해 다음 조정을 수행했습니다.

function run(){ 

     $buffer=''; 
     $i=0; 
     $j=1; 
     $date = date("m-d-y"); 
     $handle = @fopen ($this->Getsource(), "r"); 

     while (!feof ($handle)) { 

      $buffer .= @fgets($handle, 4096); 
      $i++; 

      if ($i >= $this->getLines()) { // $split was here, empty value.. 

       // set your filename pattern here. 
       $fname = $this->Getpath()."dma_map_$date.$j.csv"; 

       if (!$fhandle = @fopen($fname, 'w')) { 
        print "Cannot open file ($fname)"; 
        exit; 
       } 

       if ([email protected]($fhandle, $buffer)) { 
        print "Cannot write to file ($fname)"; 
        exit; 
       } 
       fclose($fhandle); 
       $j++; 
       unset($buffer,$i); 
      } 
     } 
     fclose ($handle); 
    } 

나는 CSV 10 개 파일로 파일을 50 만 라인을 분할이 클래스를 사용하므로 phpMyAdmin에 시간 초과 문제없이 소비 할 수 있습니다. 매력처럼 일했습니다.

1

수정 클래스가 있으며 .txt 파일로 완벽하게 작동합니다.

<?php 

/** 
* filesplit class : Split big text files in multiple files 
* 
* @package 
* @author Ben Yacoub Hatem <[email protected]> 
* @copyright Copyright (c) 2004 
* @version $Id$ - 29/05/2004 09:02:10 - filesplit.class.php 
* @access public 
**/ 
class filesplit{ 
    /** 
    * Constructor 
    * @access protected 
    */ 
    function filesplit(){ 

    } 

    /** 
    * File to split 
    * @access private 
    * @var string 
    **/ 
    var $_source = 'logs.txt'; 

    /** 
    * 
    * @access public 
    * @return string 
    **/ 
    function Getsource(){ 
     return $this->_source; 
    } 

    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function Setsource($newValue){ 
     $this->_source = $newValue; 
    } 

    /** 
    * how much lines per file 
    * @access private 
    * @var integer 
    **/ 
    var $_lines = 1000; 

    /** 
    * 
    * @access public 
    * @return integer 
    **/ 
    function Getlines(){ 
     return $this->_lines; 
    } 

    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function Setlines($newValue){ 
     $this->_lines = $newValue; 
    } 

    /** 
    * Folder to create splitted files with trail slash at end 
    * @access private 
    * @var string 
    **/ 
    var $_path = 'logs/'; 

    /** 
    * 
    * @access public 
    * @return string 
    **/ 
    function Getpath(){ 
     return $this->_path; 
    } 

    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function Setpath($newValue){ 
     $this->_path = $newValue; 
    } 

    /** 
    * Configure the class 
    * @access public 
    * @return void 
    **/ 
    function configure($source = "",$path = "",$lines = ""){ 
     if ($source != "") { 
      $this->Setsource($source); 
     } 
     if ($path!="") { 
      $this->Setpath($path); 
     } 
     if ($lines!="") { 
      $this->Setlines($lines); 
     } 
    } 


    /** 
    * 
    * @access public 
    * @return void 
    **/ 
    function run(){ 

     $buffer = ''; 
     $i=0; 
     $j=1; 
     $date = date("m-d-y"); 
     $handle = @fopen ($this->Getsource(), "r"); 

     while (!feof ($handle)) { 

      $buffer .= @fgets($handle, 4096); 
      $i++; 

      if ($i >= $this->getLines()) { 

       // set your filename pattern here. 
       $fname = $this->Getpath()."split_{$j}.txt"; 

       if (!$fhandle = @fopen($fname, 'w')) { 
        print "Cannot open file ($fname)"; 
        exit; 
       } 

       if ([email protected]($fhandle, $buffer)) { 
        print "Cannot write to file ($fname)"; 
        exit; 
       } 
       fclose($fhandle); 
       $j++; 
       unset($buffer,$i); 
      } 
     } 
     if (!empty($buffer) && !empty($i)) { 
      $fname = $this->Getpath()."split_{$j}.txt"; 

      if (!$fhandle = @fopen($fname, 'w')) { 
       print "Cannot open file ($fname)"; 
       exit; 
      } 

      if ([email protected]($fhandle, $buffer)) { 
       print "Cannot write to file ($fname)"; 
       exit; 
      } 
       fclose($fhandle); 
      unset($buffer,$i); 
     } 
     fclose ($handle); 
    } 


} 
?> 

큰 파일을 가정 사용 예

<?php 

require_once("filesplit.class.php"); 

$s = new filesplit; 
$s->Setsource("logs.txt"); 
$s->Setpath("logs/"); 
$s->Setlines(100); //number of lines that each new file will have after the split. 
//$s->configure("logs.txt", "logs/", 2000); 
$s->run(); 
?>