2011-10-29 3 views
5

큰 파일을 (잠재적으로) SD 카드에 저장하는 Android 앱을 작성했습니다. 때때로 파일이 손상된 상태로 남게되는 쓰기 작업 중에 IOException이 발생합니다. 이 질문에 대한 답변에 따라 : 내가 사용한다안드로이드에 안전하게 파일을 디스크에 저장 하시겠습니까?

Question: How to safely write to a file?

전략은 임시 파일을 생성하고 쓰기가 완료되면이 파일을 복사하는 것입니다. 내 질문 :

1) Android에서 가장 안전한 방법인가요? (예 : Android SD 카드에 파일을 복사 할 수 있습니까?)

2) 제한된 리소스 (디스크 공간)가있는 임베디드 시스템에서 디스크에 안전하게 쓰기위한 또 다른 전략을 아는 사람이 있습니까? 안전하게 가장 합리적인 플랫폼에서 파일을 만들 수

감사

+0

죄송합니다. 귀하의 질문에 잘못 이해했습니다. 나는 내 대답을 삭제했다. –

답변

10

일반적인 방법 (대신 두 개의 큰 파일을 생성하는) 임시 파일 다음 이름 바꾸기를 만드는 것입니다 (리눅스/안드로이드 그 중 하나입니다) 대답 & 질문에 언급 된대로 파일에 연결했습니다. 에 중점을 두어 이름 변경; 파일 이름 바꾸기가 인 경우 보통 원자 작업 이 같은 파일 시스템 내 일 경우 복사하지 않습니다. 또한이 방법은 데이터의 단일 사본에 충분한 공간 만 있으면됩니다.

따라서 임시 이름을 사용하여 대상 디렉토리에 파일을 만든 다음 File.renameTo()을 사용하여 적절한 이름을 지정하십시오. 임시 파일에 대한 표준 명명 규칙을 사용하면 응용 프로그램이 예를 들어 예기치 않게 종료 되더라도 항상 임시 파일을 찾고 삭제할 수 있습니다. 장치의 전원을 끈다.

당신이 정말로 편집증이 있다면, 당신은 FileDescriptor.sync() 또는 동등한에 전화를 몇 통을 삽입 할 수 있습니다 ...

편집 : BTW

, 당신은 당신이 점점 여부되어 IOException의 종류를 언급하지 않는다 당신은 그 원인을 추적했습니다. 공간이 충분하지 않아서 문제가 발생하더라도 문제가있는 SD 카드에 대해 이야기하고 있다면이 경우 '안전함'과 같은 것은 없습니다.

편집 2 :

사용 가능한 여유 공간을 확인하려면 대상 디렉토리에 대해 File 객체와 File.getFreeSpace() 전화 (파일이 끝날 것 즉 디렉토리)를 생성 할 수 있습니다. 이 수표는 보증을 제공하지 않는다는 점에 유의하십시오. 다른 프로세스는 데이터를 매체에 씁니다.

+0

분명한 답변을 보내 주셔서 감사합니다. 이름 바꾸기가 너무 의미가 있습니다. 나는 다른 질문에서 그것을 놓쳤습니다. – brif

+0

이름 바꾸기는 대답과 같을 것입니다. 그러나 당신이 쓸 준비가되어있는 파일을 SD에 충분한 빈 공간이 있는지 확인할 수 있는지 궁금합니다. – Jeff

+0

@Jeff : 더 명백한 경우를 피하기 위해 ['File.getFreeSpace()'] (http://developer.android.com/reference/java/io/File.html#getFreeSpace%28%29)를 호출 할 수 있습니다. 공간이 충분하지 않습니다. – thkala

0

복사 할 수 있을지 모르겠지만 임시 파일의 이름을 바꾸는 것이 일반적입니다. 쓰는 동안 예외가 발생하면 임시 파일을 삭제하십시오.

3

나는 이것이 너무 늦다는 것을 알고 있지만,이 문제를 우연히 만난 사람이면 누구나 도움이 될 것입니다.

AtomicFile을 사용해야합니다.

다음 코드 스 니펫이 도움이 될 수 있습니다.

private void writeFile(File file, byte[] data) { 
    file.mkdirs(); 
    try { 
     AtomicFile aFile = new AtomicFile(file); 
     FileOutputStream fos = aFile.startWrite(); 
     fos.write(data); 
     aFile.finishWrite(fos); 
    } catch (IOException ioe) { 
     Log.e(TAG, "Cannot write file " + file.getPath()); 
    } 
} 
관련 문제