programing

대용량 파일을 한 줄씩 읽는 방법

randomtip 2022. 9. 8. 21:28
반응형

대용량 파일을 한 줄씩 읽는 방법

파일을 한 줄 한 줄 읽고 싶은데 메모리에 완전히 로드하지 않고 읽고 싶습니다.

파일이 너무 커서 메모리에서 열 수 없습니다.열려고 하면 항상 메모리 오류가 발생합니다.

파일 사이즈는 1GB입니다.

를 사용할 수 있습니다.fgets()파일을 한 줄씩 읽는 함수:

$handle = fopen("inputfile.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        // process the line read.
    }

    fclose($handle);
}
if ($file = fopen("file.txt", "r")) {
    while(!feof($file)) {
        $line = fgets($file);
        # do same stuff with the $line
    }
    fclose($file);
}

파일에 객체 지향 인터페이스 클래스를 사용할 수 있습니다. http://php.net/manual/en/splfileobject.fgets.php (PHP 5 > = 5.1.0)

<?php

$file = new SplFileObject("file.txt");

// Loop until we reach the end of the file.
while (!$file->eof()) {
    // Echo one line from the file.
    echo $file->fgets();
}

// Unset the file to call __destruct(), closing the file handle.
$file = null;

사용하고 싶은 경우foreach대신while큰 파일을 열 때는 아마 캡슐화해야 할 필요가 있을 겁니다.while전체 파일을 메모리에 로드하지 않도록 제너레이터 내부에서 루프를 실행합니다.

/**
 * @return Generator
 */
$fileData = function() {
    $file = fopen(__DIR__ . '/file.txt', 'r');

    if (!$file) {
        return; // die() is a bad practice, better to use return
    }    
    while (($line = fgets($file)) !== false) {
        yield $line;
    }

    fclose($file);
};

다음과 같이 사용합니다.

foreach ($fileData() as $line) {
    // $line contains current line
}

이렇게 하면 foreach() 내의 개별 파일 행을 처리할 수 있습니다.

참고: 생성기에는 >= PHP 5.5가 필요합니다.

이 있습니다.file()파일에 포함된 행의 배열을 반환하는 함수입니다.

foreach(file('myfile.txt') as $line) {
   echo $line. "\n";
}

모든 답변에 명백한 답은 없었다.
PHP에는 바로 그 목적을 위해 만들어진 깔끔한 스트리밍 딜리미터 파서가 있습니다.

$fp = fopen("/path/to/the/file", "r");
while (($line = stream_get_line($fp, 1024 * 1024, "\n")) !== false) {
  echo $line;
}
fclose($fp);

버퍼링 기술을 사용하여 파일을 읽습니다.

$filename = "test.txt";
$source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
while (!feof($source_file)) {
    $buffer = fread($source_file, 4096);  // use a buffer of 4KB
    $buffer = str_replace($old,$new,$buffer);
    ///
}
foreach (new SplFileObject(__FILE__) as $line) {
    echo $line;
}

이것이, 매우 큰 파일(최대 100 G로 테스트 완료)로 관리하는 방법입니다.fgets()보다 빠릅니다.

$block =1024*1024;//1MB or counld be any higher than HDD block_size*2
if ($fh = fopen("file.txt", "r")) { 
    $left='';
    while (!feof($fh)) {// read the file
       $temp = fread($fh, $block);  
       $fgetslines = explode("\n",$temp);
       $fgetslines[0]=$left.$fgetslines[0];
       if(!feof($fh) )$left = array_pop($lines);           
       foreach ($fgetslines as $k => $line) {
           //do smth with $line
        }
     }
}
fclose($fh);

(!fe of...)을 조심하라.fgets()'의 경우 fgets는 에러(returnfing false)를 수신하여 파일 끝에 도달하지 않고 영원히 루프할 수 있습니다.codaddict는 가장 정확하지만 fgets 루프가 종료되면 feof를 확인합니다.그렇지 않으면 오류가 발생한 것입니다.

SplFileObject는 대용량 파일을 처리할 때 유용합니다.

function parse_file($filename)
{
    try {
        $file = new SplFileObject($filename);
    } catch (LogicException $exception) {
        die('SplFileObject : '.$exception->getMessage());
    }
    while ($file->valid()) {
        $line = $file->fgets();
        //do something with $line
    }

    //don't forget to free the file handle.
    $file = null;
}

이 질문에 대한 일반적인 해결책 중 하나에서 새 줄 문자에 문제가 발생합니다.심플하면 쉽게 고칠 수 있습니다.str_replace.

$handle = fopen("some_file.txt", "r");
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        $line = str_replace("\n", "", $line);
    }
    fclose($handle);
}
<?php
echo '<meta charset="utf-8">';

$k= 1;
$f= 1;
$fp = fopen("texttranslate.txt", "r");
while(!feof($fp)) {
    $contents = '';
    for($i=1;$i<=1500;$i++){
        echo $k.' -- '. fgets($fp) .'<br>';$k++;
        $contents .= fgets($fp);
    }
    echo '<hr>';
    file_put_contents('Split/new_file_'.$f.'.txt', $contents);$f++;
}
?>

어레이 반환 시 읽기 기능

function read_file($filename = ''){
    $buffer = array();
    $source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
    while (!feof($source_file)) {
        $buffer[] = fread($source_file, 4096);  // use a buffer of 4KB
    }
    return $buffer;
}

언급URL : https://stackoverflow.com/questions/13246597/how-to-read-a-large-file-line-by-line

반응형