클라이언트에 제공되는 데이터 파일 (예 : /srv/data
)이 들어있는 디렉토리가 있습니다. 일련의 업데이트를 진행하면서 /srv/data_tmp
을 작업 중이며 작업이 끝나면 data
을 원자 적으로 data_tmp
으로 대체하고 싶습니다. File.renameTo()
은 대상이 기존 디렉토리 인 경우 항상 false를 반환합니다. 어떻게해야합니까?Java에서 디렉터리를 원자 적으로 다른 디렉터리로 대체하는 방법은 무엇입니까?
답변
나는 두려워 할 수 없다. 최소한 SO 수준은 아닙니다. 그래서 당신이 자바 애플리케이션의 맥락에서 "원 자성"을 관리한다고 할지라도, 실제 파일 시스템 수준에서 간섭하는 다른 "불량"프로세스에 대해서는 아무런 보장이 없다.
내가 너라면 this article (상당히 오래된 것이지만 몇 가지 아이디어를 제공해야 함)을 읽고 나서 more modern version에 제안 된 방법을 이식 할 수 있는지 확인하십시오.
아, 잠깐, 누군가 this을 이미 완료했습니다. 이 목표를 달성
그리고 분명히 당신의 the first one to ask here 아닌, 하나
행운을 빕니다 ...
Apache Commons Transactions로 허용됩니다 이 자바 애플 리케이션의 컨텍스트에서 아주 깔끔한 방법으로.이게 나를 위해 충분하다. 귀하의 링크 주셔서 감사합니다! –
/srv/data
디렉토리를 기호 링크 (또는 junction in Windows XP)로 바꿀 수 있으며 적절할 경우 링크 대상을 변경할 수 있습니다. 그래도 Java 6 API에서는이를 수행 할 수 없습니다. 라이브러리에 의존하거나 명령 행 명령을 직접 작성해야합니다.
NB : 그 조작의 원 자성에 대해서는 아무런 보장을하지 않습니다.
심볼 링크 접근법은 흥미 롭습니다. 그러나 파일 이름을 이미 존재하는 파일 이름으로 바꿀 수 없다는 것은 잘못된 것입니다. '/ home/me'에 a와 b가 모두 존재하면, b는 (Mac OS X/HFS +에서)'new file ("/ home/me/a")로 b를 성공적으로 덮어 씁니다. renameTo (new File ("/home/me/b ")' –
아, 맞다. 기대하지 않았어 –
리눅스 호출 rename
시스템 호출은 이것을 허용하지 않습니다 (rename
시스템 호출은 빈 디렉토리를 덮어 쓸 수 있습니다). 그래서 나는 리눅스에서 자바로 할 수 있다고 생각합니다.
'이름 바꾸기'에 대한 호출이 원자 적입니까? 그렇다면 덮어 쓰는 경우에도 마찬가지입니까? –
네,하지만 [맨 페이지 ] (http://linux.die.net/man/2/rename) "덮어 쓸 때 oldpath와 newpath가 이름이 바뀌는 파일을 참조하는 창이있을 것입니다." –
는 중간 TMP와 함께, "심볼릭 링크"와 "이름 바꾸기"의 조합을 사용하여 완전히 가능하다 예배 규칙서. 다음의 예는 쉘,하지만 당신은 쉽게 기본 통화를 사용하는 것이 여기에 기능을 변환 할 수 있습니다 : 여기에서 가져온
mkdir -p tmp/real_dir1 tmp/real_dir2
touch tmp/real_dir1/a tmp/real_dir2/a
# start with ./target_dir pointing to tmp/real_dir1
ln -s tmp/real_dir1 target_dir
# create a symlink named target_dir in tmp, pointing to real_dir2
ln -sf tmp/real_dir2 tmp/target_dir
# atomically mv it into ./ replacing ./target_dir
mv tmp/target_dir ./
예 : http://axialcorps.wordpress.com/2013/07/03/atomically-replacing-files-and-directories/
이 (의사 코드)로 귀결를 :
mkdir('./tmp');
mkdir('./tmp/real_dir1');
mkdir('./tmp/real_dir2');
symlink('./tmp/real_dir1', './target_dir')
symlink('./tmp/real_dir2', './tmp/target_dir')
rename('./tmp/target_dir', './target_dir')
여기에서 최종 이름 바꾸기는 기본적입니다. 따라서 작업은 디렉토리를 사용하는 모든 프로세스의 시점에서 성공하거나 완전히 실패합니다. 작업은 원 자성입니다.
- 1. Java에서 어떤 작업이 원자 적으로 간주됩니까?
- 2. 원자 적으로 비교 및 증분하는 방법은 무엇입니까?
- 3. 어떻게 재귀 적으로 디렉터리를 다른 디렉터리로 복사하고 변경되지 않은 파일 만 바꿀 수 있습니까?
- 4. 디렉토리를 원자 적으로 이동
- 5. ASP.NET Web Dev : 한 디렉터리를 다른 디렉터리로 매핑 하시겠습니까?
- 6. 원자 적으로 파일에 쓰는 것의 차이점은 무엇입니까?
- 7. 여러 파일을 원자 적으로 잠그는 것
- 8. x86 ASM에서 값을 원자 적으로 읽는 방법은 무엇입니까?
- 9. 필드를 원자 적으로 유지하도록 테이블을 구성하는 방법은 무엇입니까?
- 10. gen_event 관리자에게 원자 적으로 알리고 중지합니다
- 11. 원자 변수를 사용하여 Java에서 뮤텍스 구현
- 12. 원자 적으로 파일을 만드는 가장 좋은 방법
- 13. Java에서 BufferedImage의 색상을 대체하는 방법
- 14. 원자 적으로 변화하는 복수의 열 MySQL의
- 15. Mac OS에서 원자 적으로 값을 얻으십시오.
- 16. 메소드를 원자 적으로 표시하는 방법이 있습니까?
- 17. StringReader로 StringBufferInputStream을 대체하는 방법은 무엇입니까?
- 18. 원시 MYSQL 데이터 파일을 다른 디렉터리로 이동
- 19. Java에서 다형 적으로 디스 패칭
- 20. 이클립스에서 문자열을 대체하는 방법은 무엇입니까?
- 21. 이미지 색상을 대체하는 방법은 무엇입니까?
- 22. eregi를 preg_match로 대체하는 방법은 무엇입니까?
- 23. tsql : substring을 대체하는 방법은 무엇입니까?
- 24. 하나의 IObserver에서 다른 IObserver로 원자 스위치를 구현하는 방법은 무엇입니까?
- 25. 다른 네트워크 시나리오를 시뮬레이트하는 방법은 무엇입니까? (Java에서)
- 26. java에서 다른 디렉토리의 파일을 검사하는 방법은 무엇입니까?
- 27. mysql 데이터베이스의 특정 값의 인스턴스를 다른 인스턴스로 대체하는 방법은 무엇입니까?
- 28. 제목을 다른 게시물의 링크로 대체하는 가장 좋은 방법은 무엇입니까?
- 29. 목록 항목의 존재 여부를 원자 적으로 확인하고 목록 항목을 호출하는 방법은 무엇입니까?
- 30. 날짜별로 한 디렉터리에서 다른 디렉터리로 파일 복사
기본 파일 시스템에 제약이 있습니까? 분명히 FAT라면 파일 시스템이 FAT를 지원하지 않기 때문에 아무런 방법이 없습니다. 두 디렉토리가 같은 물리적 볼륨에 있는지 여부를 알고 있습니까? 새로운 JDK7 java.nio.file API를 사용할 수 있습니까, 아니면 JDK <= 6에서 작동해야합니까? –
두 개의 파일 이동 작업이 엄밀히 말하면 "원자 적"으로 수행 될 수 있다고 생각하지 않습니다. 일부 파일 시스템은 일부 [원자 적 조작]을 보장하지만 (http://www.softpanorama.org/Internals/Filesystems/ntfs.shtml) OS에 여러 FS 작업이 모두에게 원자 적으로 수행되도록 요청하는 방법을 알지 못합니다 프로세스; 확실히 자바가 아닙니다. – maerics
@Mike : HFS +, ext3 또는 NTFS를 사용하고 FAT을 사용하지 않을 것입니다. JDK 6에서 작동합니다. –