2011-08-19 4 views
3

파일을 열어 내용을 읽은 후 원래 내용을 기반으로 파일 내용을 일부 출력으로 덮어 쓰는 가장 깨끗한 방법은 무엇입니까? 특히, 항목 목록 (줄 바꿈으로 구분)으로 채워진 파일을 열거 나 목록에 항목을 추가/처리하고 목록에서 가장 오래된 N 항목을 제거한 다음 목록을 파일에 다시 쓰려고합니다.PHP에서 파일 내용을 읽고 덮어 쓰는 가장 좋은 방법은 무엇입니까?

fopen(<path>, 'a+') 
flock(<handle>, LOCK_EX) 
fread(<handle>, filesize(<path>)) 
// process contents and remove old entries 
fwrite(<handle>, <contents>) 
flock(<handle>, LOCK_UN) 
fclose(<handle>) 

여러 페이지 요청에서 파일을 보호하려면 flock()을 사용하여 파일을 잠글 필요가 있습니다. fopen()이 트릭을 할 때 'w +'플래그가 올까요? PHP 매뉴얼은 파일 길이를 0으로 자르므로 파일의 현재 내용을 읽지 못할 수도 있습니다.

+3

다른 임시 파일에 쓰기를 제안한 다음 첫 번째 파일을 삭제하고 임시 파일의 이름을 바꾸는 것이 좋습니다. – BishopRook

+0

당신은 이것에 대한 해결책을 찾았습니까? 나는 정확하게이 시나리오에 관심이있다. (파일이 잠긴 동안 덮어 쓰기를 읽는다.) – ralbatross

답변

0

파일이 다음 가장 쉬운 (즉, 당신이 PHP의 메모리 제한을 날려하지 않습니다 확신 로딩 될 수있다), 지나치게 크지 않으면

$data = file_get_contents($filename); 

쓰기

file_put_contents($filename, $data); 
2

읽기 방법은 전체 파일을 문자열 (file_get_contents())으로 읽고, 문자열을 처리 한 다음 그 결과를 파일 (file_put_contents())에 다시 쓰는 것입니다. 파일이 너무 큰 경우 (예를 들어, 수십 또는 수백 메가 바이트) 또는 처리가 메모리 사용량이있다, 당신은 더욱 더 때 (메모리가 부족거야

  • :이 방법은 두 가지 문제가 있습니다 실행중인 인스턴스가 여러 개있는 경우).
  • 작업이 파괴적입니다. 저장이 중간에 실패하면 모든 원본 데이터가 손실됩니다.

이들 중 하나가 염려되는 경우 계획 B는 파일을 처리하고 동시에 임시 파일에 씁니다. 성공적으로 완료되면 두 파일을 모두 닫고 원본 파일의 이름을 바꾸거나 삭제 한 다음 임시 파일의 이름을 원래 파일 이름으로 바꿉니다.

+0

고마워. file_get_contents()와 file_put_contents()는 fopen(), fread(), fwrite() 및 fclose()를 대체합니다. 어떤 시점에서 파일을 잠그고 잠금 해제해야합니까? 불행히도 flock()은 파일 핸들을 필요로합니다. – Phillip

+1

원본 파일을 잠글 수 없습니다. 모든 데이터를 다른 임시 파일에 성공적으로 쓸 때까지 만지지 마십시오. 이 절차가 완료되면 - 원래 파일을 삭제하거나 이름을 바꿉니다 (잘못되었을 경우 백업용). 임시 파일의 이름을 원래 파일 이름으로 바꿉니다. 이렇게하면 실수가 잘못되어 원래 파일과 깨진 임시 파일을 쉽게 버리고 다시 시작할 수 있습니다. –

+2

다른 프로세스가 해당 파일을 변경하지 않는 한 괜찮습니다. 카운터를 생각해보십시오 ... 첫 번째 시도에서는 저장되지만 원래 파일은 잠겨 있지 않으므로 다른 프로세스에서이 파일을 쓰면 변경 될 수 있습니다. 또는 파일 잠금이 사라질 때까지 기다리는 동안 구식 정보를 읽으십시오. –

관련 문제