2009-04-03 2 views
17

동일한 파일에서 2 개 (또는 그 이상)의 FileOutputStream을 동시에 열 때 어떻게됩니까?Windows에서 Java로 동시 파일 쓰기

일부 플랫폼, 특히, 파일이 한 번에 하나의 FileOutputStream (또는 그 외의 파일 기입 객체)로 쓰기 위해 열 수 다음 Java API

이 말한다.

큰 파일 (각각 다른 파일)을 읽는 두 개의 스레드가 있고 동일한 출력 파일에 쓰기 때문에 Windows가 그러한 플랫폼이 아니라고 생각합니다. 예외가 발생하지 않고 파일이 만들어지고 두 입력 파일의 청크가 포함 된 것처럼 보입니다.

사이드 질문 :

  • 역시 유닉스에이 사실인가요?
  • 그리고 동작이 동일하기를 원하기 때문에 (실제로 한 스레드가 올바르게 쓰고 다른 스레드가 충돌 경고를 받길 원합니다) 어떻게 파일이 이미 쓰기 위해 열려 있는지 확인할 수 있습니까?

답변

16

파일에 다른 작성자 —이있을 때 수동으로 알림을받을 수있는 신뢰할 수있는 교차 플랫폼 방법이 없습니다. 즉, 파일이 이미 쓰기 위해 열려있는 경우 예외가 발생합니다. 그러나 이것을 적극적으로 확인하는 데 도움이되는 몇 가지 기술이 있습니다.

여러 프로세스 (Java와 Java가 아닌 혼합이 될 수 있음)가 파일을 사용 중일 경우 FileLock을 사용하십시오. 파일 잠금을 성공적으로 사용하기위한 핵심은 단지 "권고"임을 기억하는 것입니다. 잠금을 확인하면 잠금이 표시되도록 보장되지만 잊어 버리면 잠금이 해제되지 않습니다. 파일에 액세스하는 모든 프로세스는 잠금 프로토콜을 사용하도록 설계되어야합니다.

단일 Java 프로세스가 파일에 대해 작업하는 경우 Java에 내장 된 동시성 도구를 사용하여 안전하게 수행 할 수 있습니다. 각 파일 이름을 해당 잠금 인스턴스와 연관시키는 모든 스레드에서 볼 수있는 맵이 필요합니다. a related question에 대한 대답은 파일에 File 개체 또는 canonical paths 개체로 쉽게 적용 할 수 있습니다. 잠금 객체는 FileOutputStream이거나 스트림 주변의 래퍼 일 수도 있고 ReentrantReadWriteLock.

4

(OS에 따라 다르기 때문에) OS가 파일 상태를 결정하도록주의해야합니다. 공유 리소스가 있다면 액세스를 제한 할 것입니다. Re-entrant lock

이 잠금을 사용하면 하나의 스레드가 리소스 (파일)를 가져 와서 쓸 수 있습니다. 다음 스레드는 다른 스레드가 보유하고있는이 잠금을 확인하거나 첫 번째 스레드가 해제 할 때까지 무기한 차단합니다.

Windows (나는 생각한다)는 두 파일을 같은 파일에 쓰는 것을 제한 할 것이다. 나는 유닉스가 그렇게 할 것이라고 생각하지 않는다.

+0

하지만 쓰기를 할 때마다 차단하고 싶지 않습니다. 누군가 내가 이미 쓰고 싶은 파일에 이미 쓰고 있다면 차단하고 싶습니다. 사실, 나는 전혀 차단하고 싶지 않습니다. 두 번째 스레드에게 그가 쓸 수 없다고 말하고 클라이언트가 추가 작업을 결정하도록합니다. –

+0

CHECK 그 API를 잠급니다. 자물쇠를 검사하여 다른 사람이 이미 자물쇠를 잠그고 있는지 확인한 다음 (예 : 빵이 아닌 경우) 어떻게해야할지 결정할 수 있습니다. –

1

당신이 말하는 두 스레드가 같은 JVM에 있다면 두 스레드가 액세스하는 어딘가에 부울 변수를 가질 수 있습니다.

1

유닉스는 같은 파일에 동시 작성자를 허용합니다.

동일한 파일에 두 번 이상 쓸 수 없습니다. 당신이 있다면 디자인 결함이 있습니다.