파일을 .NET으로 작성한 후 파일을 삭제하려고합니다 FileOutputStream
. 다음은 작성에 사용하는 코드입니다.
private void writeContent(File file, String fileContent) {
FileOutputStream to;
try {
to = new FileOutputStream(file);
to.write(fileContent.getBytes());
to.flush();
to.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
보시다시피 스트림을 플러시하고 닫았지만 삭제하려고하면 file.delete()
false를 반환합니다.
나는 파일이 존재하는지 확인하기 위해 삭제 전에 확인하고, : file.exists()
, file.canRead()
, file.canWrite()
, file.canExecute()
모든 반환 사실. 이 메서드를 호출 한 직후에 시도 file.delete()
하고 false를 반환합니다.
내가 잘못한 것이 있습니까?
답변
자바의 또 다른 버그. 10 년 경력 중 두 번째에 불과했습니다. 이것은 다른 사람들이 언급했듯이 내 해결책입니다. 나는 네더를 사용했다 System.gc()
. 하지만 여기서 제 경우에는 절대적으로 중요합니다. 기묘한? 예!
finally
{
try
{
in.close();
in = null;
out.flush();
out.close();
out = null;
System.gc();
}
catch (IOException e)
{
logger.error(e.getMessage());
e.printStackTrace();
}
}
답변
효과가있는 속임수는 꽤 이상했습니다. 문제는 이전에 파일의 내용을 읽었을 때 BufferedReader
. 읽은 후 버퍼를 닫았습니다.
그동안 나는 전환했고 지금은 FileInputStream
. 또한 읽기를 마친 후 스트림을 닫습니다. 그리고 이제 작동합니다.
문제는 이것에 대한 설명이 없다는 것입니다.
나도 몰라 BufferedReader
과 FileOutputStream
호환되지 않을 수 있습니다.
답변
나는이 간단한 것을 시도했고 작동하는 것 같다.
file.setWritable(true);
file.delete();
그것은 나를 위해 작동합니다.
이것이 작동하지 않으면 Linux에서는 sudo로, Windows에서는 관리자로 Java 애플리케이션을 실행하십시오. Java에 파일 속성을 변경할 수있는 권한이 있는지 확인하기 위해서입니다.
답변
파일을 삭제 / 이름 변경하기 전에 모든 판독기 또는 작성기 (예 : BufferedReader
/ InputStreamReader
/ BufferedWriter
)가 제대로 닫혔 는지 확인해야합니다 .
파일에서 데이터를 읽고 쓰려고 할 때 파일은 프로세스에 의해 유지되고 프로그램 실행이 완료 될 때까지 해제되지 않습니다. 프로그램이 종료되기 전에 삭제 / 이름 변경 작업을 수행하려면 클래스 close()
와 함께 제공 되는 메서드를 사용해야합니다 java.io.*
.
답변
Jon Skeet이 언급했듯이, finally {…} 블록에서 파일을 닫아 항상 닫혀 있는지 확인해야합니다. 그리고 e.printStackTrace로 예외를 삼키는 대신 단순히 예외를 포착하여 메서드 서명에 추가하지 마십시오. 어떤 이유로 든 할 수 없다면 최소한 다음과 같이하십시오.
catch(IOException ex) {
throw new RuntimeException("Error processing file XYZ", ex);
}
이제 질문 2 번 :
이렇게하면 :
...
to.close();
System.out.println("Please delete the file and press <enter> afterwards!");
System.in.read();
...
파일을 삭제할 수 있습니까?
또한 파일이 닫히면 플러시됩니다. IOUtils.closeQuietly (…)를 사용하므로 파일을 닫기 전에 파일 내용이 있는지 확인하기 위해 flush 메서드를 사용합니다 (IOUtils.closeQuietly는 예외를 발생시키지 않음). 이 같은:
...
try {
...
to.flush();
} catch(IOException ex) {
throw new CannotProcessFileException("whatever", ex);
} finally {
IOUtils.closeQuietly(to);
}
그래서 나는 파일의 내용이 거기에 있다는 것을 알고 있습니다. 일반적으로 파일의 내용이 기록되고 파일을 닫을 수 있는지 여부가 아니라 파일이 닫혔는지 여부는 중요하지 않습니다. 귀하의 경우 중요하므로 파일을 직접 닫고 예외를 처리하는 것이 좋습니다.
답변
이 파일을 삭제할 수없는 이유는 없습니다. 이 파일을 누가 보유하고 있는지 확인하겠습니다. 유닉스 / 리눅스에서는 lsof 유틸리티를 사용하여 파일에 잠금이있는 프로세스를 확인할 수 있습니다. Windows에서는 프로세스 탐색기를 사용할 수 있습니다.
lsof의 경우 다음과 같이 간단합니다.
lsof /path/and/name/of/the/file
프로세스 탐색기의 경우 찾기 메뉴를 사용하고 파일 이름을 입력하여 파일을 잠그는 프로세스를 가리키는 핸들을 표시 할 수 있습니다.
여기에 필요한 작업을 수행하는 코드가 있습니다.
FileOutputStream to;
try {
String file = "/tmp/will_delete.txt";
to = new FileOutputStream(file );
to.write(new String("blah blah").getBytes());
to.flush();
to.close();
File f = new File(file);
System.out.print(f.delete());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
OS X에서 잘 작동합니다. Windows에서 테스트하지는 않았지만 Windows에서도 작동해야한다고 생각합니다. 또한 Windows wrt 파일 처리에서 예상치 못한 동작이 있음을 인정할 것입니다.
답변
Eclipse IDE에서 작업하는 경우 이전 애플리케이션 실행에서 파일을 닫지 않았 음을 의미 할 수 있습니다. 파일을 삭제하려고 할 때 동일한 오류 메시지가 표시되는 것이 그 이유였습니다. Eclipse IDE는 응용 프로그램 종료 후 모든 파일을 닫지 않는 것 같습니다.
