2009-09-02 7 views
4

입력 파일을 대체 할 수 있도록 입력 파일과 출력 파일 모두에 동일한 파일 이름을 내 프로그램에 사용할 가능성을 추가하는 방법에 대해 생각합니다. ,열린 파일을 제거하는 것이 안전합니까()?

/* input == output in this case */ 
FILE *inf = fopen(input, "r"); 
remove(output); 
FILE *outf = fopen(output, "w"); 

을 (물론 : 처리 된 파일이 상당히 크다고 할 수있다으로

, 나는 그 가장 좋은 방법은 그런 즉, 파일을 열고 다음을 제거하고 새로 만들 첫번째로 것 같아 오류 처리 추가됨)

모든 시스템에서 열려있는 파일을 제거 할 수있는 것은 아니며,이 경우 remove()이 실패하는 한 허용됩니다.

열려있는 파일을 제거하고 그 내용을 읽지 못하게하는 시스템이 없다면 걱정됩니다.

C99 표준은이 경우 동작을 '구현 정의'로 지정합니다. SUS는 그 사건을 언급하지 않습니다.

의견/경험이 뭔가요? 걱정해야합니까? 그런 해결책을 피하는 것이 좋습니까?

EDIT : 사용자가 입력 파일과 출력 파일 모두에서 동일한 파일 이름을 지정하는 경우이 파일은 일부 주요 기능이 아니라 '최후의 수단'으로 사용됩니다.

EDIT : Ok, 다음 질문 하나만 더 :이 특별한 경우에는 저에게 제안 된 솔루션이 출력 파일을 쓰기 전용으로 열 때보 다 더 악할 수 있습니다 (예 : remove() 요구).

+6

귀중한 데이터 파일에 응용 프로그램을 사용하지 말 것을 상기하여주십시오. –

+0

README에 전용 경고가 충분합니까? 아니면 ebuild의'pkg_postinst()'에 경고를 추가해야합니까? (; –

+0

두 파일 이름이 같으면 확실히 진행해야합니까? 사용자에게 로그 또는 콘솔에 다른 이름을 입력하라는 메시지가 표시 될 수 있습니까? – vpram86

답변

4

아니요, 아니요, 안전입니다. 파일 시스템에서는 작동하지만 다른 시스템에서는 실패 할 수 있습니다. 또는 간헐적으로 실패 할 수 있습니다. 실제로 운영 체제 및 파일 시스템에 따라 다릅니다. Solaris에 대한 자세한 내용은 article on file rotation을 참조하십시오.

GNU sed's '--in-place' option을 살펴보십시오. 이 옵션은 출력을 임시 파일에 쓴 다음 원본을 복사하여 작동합니다. 이것은 안전하고 호환 가능한 유일한 방법입니다.

또한 정전이나 프로세스가 종료되어 프로그램이 언제든지 실패 할 수 있다고 생각해야합니다. 이 경우 원본 파일이 손실됩니다. 또한 참조 카운트가있는 파일 시스템의 경우 임시 파일 솔루션에 비해 공간을 절약하지 않아도됩니다. 두 파일이 입력 파일이 닫힐 때까지 디스크에 있어야하기 때문입니다.

파일이 크고 공간이 비싸고 개발자 시간이 저렴한 경우 읽기/쓰기 용으로 하나를 열어서 쓰기 포인터가 읽기 포인터를 넘어서지 않도록 할 수 있습니다.

+0

예,이 문제점을 알고 있습니다. 서사시 오류를 일으킬 수있는 방법에 대해 더 많이 생각했습니다. 사용자가 입력과 출력 모두에 대해 동일한 파일을 지정한 경우 가능합니다. –

+1

이것은 항상 임시 파일에 출력을 쓰는 것의 가치 중 일부입니다. 또한 신중하게 입력을 두 번째 임시 이름으로 바꾸고 출력 임시 이름을 최종 이름으로 변경 한 다음 모든 것이 성공한 경우에만 입력을 삭제할 수 있습니다. 유스 케이스가 입력을 .bak 또는 그와 같은 것으로 유지하고자한다면, 그에 따라 더 많은 작업을 수행해야합니다. – RBerteig

+0

당신은 정말로 옳습니다, 나는 그것에 대해 완전히 잊었습니다. 문제는 그것이 현재의 출력 방법과 충돌 할 것이지만 다음 질문에서 유용할지 묻습니다. –

4

열린 파일을 제거하도록하는 모든 시스템에서 파일 노드에 대한 참조 계산 방식을 구현합니다. 따라서 파일을 제거하면 디렉토리 항목이 제거되지만 파일 노드 자체에는 여전히 열린 파일 핸들에서 하나의 참조가 있습니다. 그러한 구현에서, 파일을 제거하는 것은 분명히 그것을 읽는 능력에 영향을 미치지 않을 것이고, 나는이 행동을 구현하는 다른 합리적인 방법을 상상하기가 어렵다.

1

저는 항상 Linux/Unix에서 작동하도록했습니다. 절대로 Windows, OS/2 또는 DOS에서. 당신이 염려하는 다른 어떤 플랫폼?

이 동작은 실제로 임시 디스크 공간을 사용할 때 유용합니다. 파일을 읽기/쓰기로 열고 바로 삭제하십시오. 그것은 프로그램 종료시 (정전 등 어떤 이유로 든) 프로그램 종료시 자동으로 정리되고, 다른 사람들이 그것을 모니터하는 것이 훨씬 더 어렵지만 불가능하지는 않습니다 (/ proc은 프로세스에 대한 읽기 권한이있는 경우 단서를 줄 수 있습니다) .

+0

Pavel Minaev는 Microsoft의 개발자이며, Windows의 정반대입니다 ... –

+0

링크가 있습니까? – Tanktalus

+1

Windows에서 작동하지 않는다는 메시지는 어디에 있습니까? –

관련 문제