2013-12-09 3 views
0

그래서 자바 애플리케이션이 파일을 작성해야하는 Samba 파일 서버가 있습니다. 문제는 새로운 파일에 대해 동일한 디렉토리를 적극적으로 가져 오는 또 다른 PHP 응용 프로그램 (PHP 스크립트가 응용 프로그램으로 간주되는 경우)이 있다는 것입니다.미래 파일 잠그기

Java 응용 프로그램에서 디스크에 완전히 기록하기 전에 PHP 스크립트가 파일을 가져 오는 경우가 있습니다. 여기에 아스키 아트의 약간은 내가 현재 가지고있는 시각화하기 위해 (그러나 작동하지 않습니다)입니다 :

Samba 공유

/foo

/bar ((내 자바 응용 프로그램은 여기에 파일을 삭제) PHP가 당기는 디렉토리)

내가 현재하고있는 것은 파일이 몇 가지 기준을 충족 할 때 /bar으로 이동 한 다음 더 많은 처리를 위해 PHP에서 가져온 것입니다. 나는 다른 것을 시도했다. 그러한 파일을 쓰기가 불가능하고 읽을 수 없도록 설정하는 것은 renameTo을 호출하기 전에했다.

조금 보았는데 FileLock님께 서 보았지만 향후 파일을 잠글 수없는 것 같습니다. 그래서 저는 여기에 어떤 종류의 가능성이 있는지 궁금합니다. PHP를 만지지 않고 파일을 완전히 작성하기 전에 파일을 잠그지 않고 잠글 수 있습니다. (왜냐하면, 음, PHP이고 지금 당장 수정할 수있는 권리가 없기 때문입니다.)

감사

편집 한 내가 어떤 식 으로든 도움을 줄 수있는 경우 PHP 스크립트가 정말 무엇을하고 있는지에 대한 몇 가지 통찰력을 가지고

.

루프에서 디렉토리 파일을 읽는 중입니다 (잠자기없이 readdir 사용).

"."이외의 파일 이름을 찾으면 바로. 그리고 "..", 그것은 file_get_contents 호출하고 자바 코드도 readdirfile_get_contents 사이를 쓸 시간이 없었 수 있으므로 파일을 완전히에도이 디스크에 기록 (또는하지하지 않기 때문에 실패하는 곳이다.

편집 2이 Java 응용 프로그램이 오래된 PHP 스크립트를 대체

. 그들은 그것을 구현 될 때, 그들은 내가 지금 데 같은 문제. 그들은 (file_put_contents와) /bar/tmp에 새 파일을 작성하여 그것을 해결을했고, 그런 다음 rename을 사용하여 bar로 이동합니다 (이름이 원자 일 것으로 예상되는 것처럼 보임). 그리고 지금까지 제대로 작동했습니다. t 자바는 PHP가하는 것보다 더 나은 것을 할 수 없다 ...

+0

/foo와/bar가 같은 파일 시스템에 있습니까? – rob

+0

@rob 예, 그렇습니다. – ALOToverflow

답변

0

나는 이것이 읽기 잠금이 공유된다는 사실 때문에 생각한다. (다중 프로세스는 같은 파일에 읽기 잠금을 적용하고 함께 읽을 수있다.)

/bar/file1은 복사가 완료되지 않은 반면 별도의 임시 잠금 파일 (예 : /bar/file1.lock)을 만드는 것이 한 가지 방법입니다. 파일 복사가 끝나 자마자 잠금 파일을 삭제하십시오.

그런 다음 PHP 코드를 변경하여 파일이 읽히기 전에 잠글지 않도록하십시오.

+0

나는 같은 생각을 가지고 있었지만 불행히도 PHP를 수정하는 것이 선택 사항이 아니라는 내용의 질문이있었습니다. – rob

0

당신은 FileLock을 시도 언급하지만, 그 방법에 대한 Javadoc을 염두에 면책 조항을 유지 : 잠긴 영역의 내용이 시스템 잠금이 실제로 외의 프로그램으로부터 액세스 할 수 없게 여부

- 종속적이므로 미정. 일부 시스템의 기본 파일 잠금 기능은 뿐이므로 프로그램에서 데이터 무결성을 보장하기 위해 알려진 잠금 프로토콜 인 을 협조해야합니다. 이 방법의 동작의

많은 측면 본질적으로 플랫폼에 따라 달라집니다 : 이름 바꾸기 작업을

당신은 또한 일부 (javadoc 내에서 언급)주의 사항이있는, File.renameTo를 사용하는 언급 또 다른 하나 개의 파일 시스템에서 파일을 이동하지 못할 수 있습니다, 그것은 원자되지 않을 수도 있습니다, 그것은

대신성공하지 않을 수 있습니다, Files.moveATOMIC_MOVE 옵션을 사용해보십시오. 을 잡아야하며 원자 이동이 불가능한 경우 대체 대안으로 넘어갈 수도 있습니다.

당신은,이 예에서 원래의 디렉토리 엔트리를 (삭제 Files.createLink(Paths.get('/foo/myFile'), 'Paths.get('/bar/myFile'))와 하드 링크를 만들 수 /foo/myFile.

는 PHP에 수정을 필요로하지 않는 간단한 해결 방법은 쉘 명령을 사용하는 것을 실패 또는 시스템 콜을 사용하여/foo에서/bar로 파일을 옮길 수 있습니다. 예를 들어, 을 사용하여 mv으로 전화하거나 ln을 호출하여/bar에서 심볼릭 링크 또는 하드 링크를 만들 수 있습니다. mv과 동일한 문제가있을 수 있습니다. foo와/bar는 다른 파일 시스템에 있습니다.

만약 당신이 루 t 서버에 대한 권한이 없으면 필수 파일 잠금을 구현할 수도 있습니다. C에서 example을 발견했지만 Java에서 C 프로그램을 호출하거나 JNA (또는 처벌하려는 경우 JNI)을 사용하여 Java로 예제를 적용 할 수 있습니다.

+0

ATOMIC_MOVE 옵션은 다른 작업을 수행하지 않습니다. 파일이 디스크에 완전히 기록되기 전에 픽업 중입니다. ProcessBuilder와 함께 이상한 예외가 있는데, 파일/경로가 존재하지 않는다고 (오류 = 2), 콘솔의 정확한 명령 줄을 붙여 넣으면 작동합니다 ... – ALOToverflow

+0

콘솔에서 명령 줄을 붙이면 작동합니다. 실행한다는 의미인가요? PHP 스크립트가 불완전한 파일을 가져 오는 문제도 해결할 수 있습니까? ProcessBuilder 코드와 스택 트레이스를 질문에 추가하십시오. – rob

+0

그것은 실행하고 지금까지도 PHP로 문제를 해결했습니다. 질문에 대해 더 많은 내용을 추가하겠습니다. – ALOToverflow