문제

저는 C 및 C++ 환경에서 왔지만 일부 웹 관련 작업도 수행합니다.우리 C 사람들 모두는 (희망적으로) 그 소명을 알고 있습니다 feofFILE* 읽기 전에 오류가 발생했습니다.이것은 C 및 C++ 초보자를 매우 자주 괴롭히는 것입니다.PHP 구현에서도 마찬가지인가요?

파일이 소켓이거나 읽기를 마치기 전에 크기를 알 수 없는 다른 것일 수 있기 때문이라고 생각합니다.그러나 거의 모든 PHP 예제( php.net 나는 다음과 같은 모습을 본 적이 있습니다. (그리고 내 머릿속에서 알람이 울립니다.)

$f = fopen("whatever.txt", "rb");
while(!feof($f)) {
    echo fgets($f);
}
fclose($f);

나는 다음과 같이 작성하고 이 문제를 피하는 것이 바람직하다는 것을 알고 있습니다.

$f = fopen("whatever.txt", "rb");
while($line = fgets($f)) {
    echo $line;
}
fclose($f);

하지만 그건 요점이 아니다."잘못된 방식"으로 수행하면 작업이 실패하는지 테스트해 보았지만 잘못된 동작이 발생하도록 할 수 없었습니다.이것은 과학적이지는 않지만 시도해 볼 가치가 있다고 생각했습니다.

그럼 전화한 게 잘못된 건가요? feof 전에 fread PHP로?

PHP가 C 버전과 다르게 이를 수행할 수 있는 몇 가지 방법이 있지만 단점도 있다고 생각합니다.

  • 기본값을 !EOF로 설정할 수 있습니다.일부 특수한 경우에는 올바르지 않을 수 있으므로 이는 차선책입니다.

  • 그들은 도중에 파일 크기를 얻을 수 있었습니다 fopen 호출하지만 모든 유형의 파일 리소스에서 작동할 수 없으므로 일관되지 않은 동작이 발생하고 속도가 느려집니다.

도움이 되었습니까?

해결책

PHP는 사용자가 파일을 읽으려고 시도할 때까지 파일이 파일 끝에 있는지 여부를 알 수 없습니다.다음의 간단한 예를 시도해 보세요.

<?php 
$fp = fopen("/dev/null","rb"); 
while (!feof($fp)) { 
    $data = fread($fp, 1);
    echo "read " . strlen($data) . " bytes";  
} 
fclose($fp); 
?>

당신은 한 줄의 독서를 얻을 것입니다 read 0 bytes.feof()는 기술적으로 파일 끝에 있더라도 true를 반환했습니다.일반적으로 이는 문제를 일으키지 않습니다. fread($fp, 1) 데이터가 반환되지 않으며 수행 중인 처리가 무엇이든 데이터를 제대로 처리하지 않습니다.파일의 끝에 있는지 정말로 알고 싶다면 먼저 읽어야 합니다.

다른 팁

이것은 답변이라기보다 질문에 더 가깝습니다. 하지만 사용하지 않으시겠어요? file_get_contents()?내 경험에 따르면 파일이나 스트림을 읽는 경우 이 함수가 대신 작업을 수행합니다(전체 리소스를 문자열로 읽거나 한계 및 오프셋을 알고/계산할 수 있다고 가정).그 자매 함수인 file_put_contents()는 반대로도 잘 작동합니다.

예를 들어, 다음은 예입니다.

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("/path/to/file.txt");
if ($expected_content != $real_content){
   file_put_contents("/path/to/file.txt", $real_content);
}

또는 스트림:

$expected_content = "Hello Stack Overflow!"
$real_content = file_get_contents("http://host.domain.com/file.txt");
if ($expected_content != $real_content){
   $options = array('ftp' => array('overwrite' => true));
   $stream = stream_context_create($options); 
   file_put_contents("ftp://user:pass@host.domain.com/file.txt", $real_content, 0, $stream);
}

그러면 EOF나 다른 것에 대해 걱정할 필요가 없습니다. EOF가 대신해 줍니다(ftp put은 약간 위험하지만 괜찮습니다).물론 이것이 모든 상황에서 작동하는 것은 아닙니다.

이 접근 방식을 실현 불가능하게 만드는 원래 질문에서 누락된 것이 있습니까?

전화하지 말라는 당신의 주장 feof 전에 fread 올바르지 않습니다. 결과적으로 질문은 유효하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top