2017-11-22 6 views
2

을 (이것은 매우 광범위한 이후 가상의 문제이며, 해결 방법은 특정 경우에 존재한다.)원자 쓰기 바이트 []

는 원자 FileOutputStream 또는 FileWriter 같은 파일에 byte[]을 (쓰기 가능 파일로?

쓰기에 실패하면 배열의 일부가 쓰여지는 것이 허용되지 않습니다. 예를 들어, 배열이 1,000,000 바이트이고 디스크가 500,000 바이트 후에 가득 차 있다면 파일에 바이트를 쓰거나 변경 사항을 기록해야합니다 어떻게 되든지 롤백해야합니다. 중간에 물리적으로 매체가 분리 된 경우에도 마찬가지입니다.

배열의 최대 크기를 알고 있다고 가정하십시오.

+0

디스크가 실제로 연결이 끊어지면 더 이상 파일을자를 수 없습니다. 따라서 'XXX.YYY.part' 파일을 작성해야하며 완료되면 이전 XXX.YYY를 제거하고 이름을 변경하십시오. –

답변

4

파일에 대한 원자 쓰기가 불가능합니다. 운영 체제는이를 지원하지 않으며 프로그래밍 언어 라이브러리가 지원하지 않기 때문에 프로그래밍 언어 라이브러리도이를 지원하지 못합니다.

기존 파일 시스템에서 파일을 가져 오는 최선의 방법은 원자 파일 이름 바꾸기입니다. 즉

  1. 가 이전을 통해 새로운 파일의 이름을 변경 기록이 새 파일을 보장하기 위해 이전

  2. 사용 FileDescriptor.sync()로 동일한 파일 시스템에 새로운 파일을 작성; 예 : CopyOptions ATOMIC_MOVE

    java.nio.file.Files.move(Path source, Path target, 
              CopyOption... options) 
    

    를 사용하여. javadocs에 따르면 지원되지 않을 수 있지만 지원되지 않는 경우 예외가 발생합니다.

하지만 원어민 성은 OS에서 구현되며 OS가 충분히 강력한 보장을 제공 할 수 없다면 운이 없다는 것에 유의하십시오.

(하드 디스크 오류가 발생할 경우 하나의 문제가 발생할 수 있습니다. 디스크가 완전히 죽으면 원 자성은 문제가됩니다.) 그러나 장애가 발생한 후에도 OS가 여전히 디스크를 읽을 수 있으면 결과는 달라집니다 파일 시스템을 복구 할 수있는 OS의 능력).

+0

왜'File # renameTo'가 아닌'Files.move'가 btw입니까? 단순히 첫 번째 것이 원 자성을 지원하기 때문일 수 있습니까? – Eugene

+2

아니요. '이동'과 'ATOMIC_MOVE'를 사용하면 응용 프로그램 작성자 **가 이동이 원 자성이거나 예외가 발생한다는 것을 알고 있습니다. 'rename '을 사용하면 원 자성이 지정되지 않으므로'이름 바꾸기 '가 실패하는 상황이 발생할 수 있습니다. –