2014-01-24 6 views
1

한다고 가정을 아끼지 :
> UndeletableFile
> File4파일 삭제 - 나는 다음과 같은 I 디렉토리 구조를 가지고 무고한

>

MyDirectory
을 File1
>을 File2
> 파일은 File3을

또한 폴더의 내용을 삭제하고 폴더 자체를 삭제하기위한 재귀 알고리즘을 구현했으며/또는 우수 제안 중 하나를 사용했다고 가정합니다. here

이제 웹에서 검색 할 때 해결책을 찾지 못하는 캐치가 있습니다.
전체 폴더를 삭제하고 싶지만 성공하려면 해야합니다. 모든 파일 및 하위 폴더에 있습니다. 현재 구현 (정확히는 java.io.File.delete())은 파일이 호출되면 즉시 삭제하고 다음 파일로 이동합니다. 위의 예와 같이 폴더 삭제가 중간에 실패하면 UndeletableFileFile5MyDirectory이 시스템에 남습니다.

이 경우에는 convenince 메서드 또는 모범 사례 알고리즘이 있습니까?
목표는 입니다. 작업이 일 경우이 중도에 실패하면 삭제할 수있는 파일을으로 보냅니다. 결국 집이 살아남을 수 있다면 그들은 죽지 않아야 할 것입니다. 내가 지금까지에 대한 생각은 무엇

:
어쩌면 너무

MyDirectory
> File1temp
> File2temp
>처럼, 그들을 삭제하는 첫 번째 대신 모든 파일 이름을 바꿀 스마트 될 것입니다 ..

그 후에 프로세스가 실패하면 다시 모든 파일을 정상적으로 이름을 바꿀 수 있으며 성공하면 정상적으로 삭제할 수 있습니다.

하지만이 솔기가 나에게 매우 비효율적인데, 더 좋은 해결책이 아닌가요? 일반적인 문제 여야하는 것처럼 보입니다. 간과했으면 링크를 제공하십시오.

+0

누가 응용 프로그램 외에이 파일을 사용합니까? 누가 그들을 생산합니까? 다른 과정? 그것은 귀하 또는 타사 소프트웨어에 의해 관리됩니까? – Mikhail

+0

@Mikhail 사용자가 직접 폴더에 영향을 줄 수 있습니다. 그들은 다른 응용 프로그램에 의해 생성됩니다. 그 당시 다른 프로세스가 실행 중이 아닙니다. 내가 관리해. **하지만 스트레스를 받고 싶습니다. ** 지금은 실패하면 괜찮습니다. 그런 다음 무언가가 발생하면 "아무것도 지우지 마십시오"로 돌아갈 수 있기를 원합니다. – avalancha

답변

2

완전히 안전한 방법은 없습니다.

가장 좋은 방법은 모든 파일을 검사하여 파일을 삭제할 수 있는지 확인하는 것입니다. 검사가 성공한 경우에만 실제 삭제를 수행합니다.

캐치는 검사 후 잠긴 것이지만 삭제하기 전에 해당 파일에서 삭제가 계속 실패하는 것입니다.

유일한 대안은 모든 삭제가 성공할 때까지 모든 파일의 사본을 보관함 (휴지통으로 옮기거나 우편 번호에 저장하는 등)이며, 그 다음에 빈을 비우거나 지퍼를 삭제하십시오 - 복원하지 않는 경우.

하지만 복원을 막기 위해 무언가가 발생할 수도 있습니다.

실제로 여기에 엣지 케이스가 있습니다. 필요한 작업은 무엇인지 식별하고 각각의 경우에 원하는 동작을 결정하는 것입니다.

+0

최선을 다하는 방법을 자세히 알아볼 수 있습니까? 'm'이 (가) "삭제 하시겠습니까?" – avalancha

+0

도움이 될만한 내용은 다음과 같습니다. http://docs.oracle.com/javase/7/docs/api/java/io/File.html#canWrite%28%29 –

+0

필자는 파일을 복사/이동하는 것이 좋습니다. 이름 바꾸기의 아이디어보다 더 많은 일을하지만, 좋은 대답 이외에, 감사합니다. – avalancha

0

먼저 비파괴적인 방법을 사용하여 삭제할 수있는 파일이 있는지 확인할 수 있습니다 (예 : UNIX에서 파일 자체와 포함 디렉토리가 쓰기 가능한지 확인하십시오. 그런 다음 삭제할 수있는 디렉토리를 재귀 적으로 계산 한 다음 두 번째 패스에서 삭제 가능한 것으로 계산 된 디렉토리 내에있는 파일과 디렉토리를 삭제합니다. 이 방법의 문제점은 작업이 진행되는 동안 다른 사람이 디렉터리 나 파일 내용 또는 사용 권한을 수정할 수 있으므로 여전히 잘못된 결과가 발생할 수 있다는 것입니다.

이름 바꾸기는 프로그램에 파일이나 디렉터리에 대한 핸들이 있으면 개체의 이름이 변경되는 동안 해당 핸들을 유지할 수 있기 때문에 바보가 아닙니다. 따라서 파일의 이름을 바꾸거나 안전한 위치로 옮기더라도 다른 사람이 파일에 대해 열린 핸들이 있으면 권한을 변경할 수 있습니다.

기본 파일 시스템이 다른 프로세스에서 동시에 조작 될 수 있기 때문에 모든 조건에서 모든 플랫폼에서 작동 할 수있는 바보 같은 방법은 없습니다.

단일 사용자 시나리오의 경우 첫 번째 단락에서 설명한 두 단계 통과 방법을 사용해야합니다.

1

여러 파일을 독점적으로 사용해야하는 경우 일반적으로 파일 세분화 작업을 시작하기 전에 별도의 세마포 파일을 잠그는 것이 좋습니다. 이 File 구성 요소의에서 유사한 접근 방식은 아파치 카멜 통합 프레임 워크에서 가져온 것입니다

private static RandomAccessFile raf; 

public static void main(String[] args) throws IOException { 
    lock(); 
    //do smth... 
    release(); 
} 

private static boolean lock() throws IOException { 
    File f = new File("Semaphore.lck"); 
    raf = new RandomAccessFile(f, "rw"); 
    FileLock fl = raf.getChannel().tryLock(); 
    return fl != null; 
} 

private static void release() throws IOException { 
    raf.close(); 
} 

이 봐 :처럼 아주 원시적 예를 보일 것이다. 유일한 문제는 두 번째 프로세스가 동일한 프로토콜을 따라야한다는 것입니다. 그렇지 않으면 아무런 효과가 없습니다.

+0

좋은 생각입니다! 그러나 나는 이것을 팀의 답과 결합해야한다는 것을 정확하게 이해합니까? 이 파일이 현재 내가 처음으로 잠글 수 있는지 여부를 확인하지 않기 때문에, 맞습니까? – avalancha

+0

사용자가 수동으로 파일에 액세스하지 않고 모든 것이 세마포어 기반 프로토콜을 통해 수행되면 파일의 이름을 바꿀 필요가 없습니다. 세마포어가 확보되면 파일을 안전하게 삭제할 수 있습니다. 이것은 java의 동기화 된 블록과 매우 흡사합니다. – Mikhail

+1

예, 세마포어 파일은 잘 작동하지만 세마포어 파일을 사용하는 모든 파일에 액세스하는 경우에만 가능합니다. 파일을 무시한 한 프로세스/사용자조차도이를 깨뜨릴 수 있습니다. –

관련 문제