2010-02-15 2 views
19

특정 작업 관련 명령이 포함 된 파일을 읽기 위해 cron에서 다소 자주 호출되는 프로세스가 있습니다. 내 프로세스는이 데이터 파일을 읽고 쓸 필요가 있으며이 시간 동안 다른 프로세스가 데이터 파일을 만지지 못하도록 잠 가야합니다. 완전히 분리 된 프로세스는 사용자가 동일한 데이터 파일에 쓰기 (쓰기) 또는 추가 (잠재적) 할 수 있습니다. 이 두 프로세스가 좋게 플레이하고 파일을 한 번에 하나씩 만 액세스하도록합니다.읽기 및 쓰기 용 Java FileLock

nio FileLock은 필자가 필요로하는 것처럼 보였지만 (자신의 세마포어 유형 파일 작성에 부족함), 읽기 위해 잠글 때 문제가 있습니다. 잠그고 쓸 수는 있지만, 읽을 때 잠금을 만들려고 할 때 NonWritableChannelException이 발생합니다. 파일을 읽기 위해 잠글 수 있습니까? RandomAccessFile이 내가 필요한 것에 더 가깝게 보이지만 구현하는 방법을 알지 못합니다.

FileInputStream fin = new FileInputStream(f); 
FileLock fl = fin.getChannel().tryLock(); 
if(fl != null) 
{ 
    System.out.println("Locked File"); 
    BufferedReader in = new BufferedReader(new InputStreamReader(fin)); 
    System.out.println(in.readLine()); 
      ... 

예외는 FileLock 라인에 발생합니다 : 여기

실패 코드입니다.

java.nio.channels.NonWritableChannelException 
at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source) 
at java.nio.channels.FileChannel.tryLock(Unknown Source) 
at Mover.run(Mover.java:74) 
at java.lang.Thread.run(Unknown Source) 

JavaDoc을 보면,이 시도가 처음은 write를 위해서 오픈되어 있지 않았던 채널에 쓰기를했을 때에 슬로우

체크되지 않는 예외는 말한다.

하지만 필자는 반드시 글을 쓸 필요는 없습니다. 필자는 FileOutpuStream 등을 작성하려고 할 때 동일한 파일에서 FileInputStream을 열 때까지 행복합니다.

+0

3 개의 param 메서드 호출, FileLock 잠금 (긴 위치, 긴 크기, 부울 공유)을 사용해 보셨나요? 필자는 전에 FileLock을 사용 해본 적이 없으므로 대답으로 게시하지는 않겠지 만 공유 잠금이 필요하고 독점 잠금이 필요하지 않은 것처럼 들리므로 그 메소드 호출을 사용하면 도움이 될 것 같습니다 그것에 자물쇠가있다. – ChadNC

+0

그 의도는 파일의 일부분 만 잠그는 것이라고 생각합니다. 그러나 모든 파일을 잠궈 서 손상을 방지하고 싶습니다. – bobtheowl2

답변

16

(a) 파일을 잠그면 잠금을 사용하지 않는 한 다른 프로세스가 파일을 만지지 못하게됩니까?
(b) 쓰기 가능한 채널을 통해 잠글 수 있습니다. 'rw'모드에서 RandomAccessFile을 통해 잠금을 가져온 다음 FileInputStream을 엽니 다. 둘 다 닫아야합니다!

+1

a) 예, 두 프로세스를 모두 작성하여 두 가지 모두에서 유사한 잠금 프로 시저를 구현할 계획입니다. b) RandomAccessFile에 직접 잠금을 설정할 수 있다는 것을 몰랐습니다. File [Input | Output] Stream을 사용하려면 새로운 FileInputStream (raf.getFD())을 수행해야했습니다. 그러나, 어느 쪽이든 직접 RandomAccessFile 개체의 입력 스트림을 사용하여, 나는 여전히 파일에서 읽을 수 있습니다. 감사합니다 – bobtheowl2

+0

응? (a) RandomAccessFile에서 직접 잠금을 얻을 수 없다면 FileChannel을 먼저 가져와야합니다. (b) RandomAccessFile에는 입력 스트림이 없지만 DataInput을 구현하므로 직접 읽을 수 있습니다. – EJP

10

tryLock(0L, Long.MAX_VALUE, true)을 사용하여 잠금을 만든 경우 더 좋을 것입니다.

이렇게하면 독서에 적합한 공유 잠금 장치가 만들어집니다.

tryLock()tryLock(0L, Long.MAX_VALUE, false)의 줄임말이며, 즉 독점 쓰기 잠금을 요청합니다.

+0

훌륭한 답변입니다. 이 프로그램은 이미 사용 중이지만 다음 단계에서 업데이트 될 수 있습니다.독점적 인 잠금 장치가 특정 시나리오에서 복잡해지면서 이제는 사용법이 많이 사용되고 있습니다. 다음 업데이트를 위해이 사실을 명심하십시오. – bobtheowl2

+0

공유 잠금 장치가 독서를 위해해야 ​​할 올바른 이유는 분명히 유스 케이스에 달려 있다고 할 수 있습니다. 많은 프로세스 중 하나만이 파일을 읽도록하려는 경우 (예 : 업로드 디렉토리를 모니터링하는 에이전트가 새 파일을 처리하는 경우) 공유 잠금이 필요하다고 생각하지 않습니다. – codebox

+1

독서가 상호 배타적이지 않기 때문에 나는 그것을 썼다. 쓰기가 항상 배타적 인 동안 여러 스레드가 간섭없이 하나의 파일을 읽을 수 있습니다. 이것은 원래의 질문에 대한 대답이었으며 모든 상황에 대한 절대적인 진리로서의 의미가 아니라는 점을 명심하십시오. 하지만 99 %의 유스 케이스에서도 마찬가지입니다. – Huxi