Java 임시 파일은 언제 삭제됩니까?


92

메소드를 사용하여 Java에서 임시 파일을 작성한다고 가정하십시오.

File tmp = File.createTempFile(prefix, suffix);

delete()메서드를 명시 적으로 호출하지 않으면 언제 파일이 삭제됩니까?

직관적으로 JVM이 종료되거나 이전에 (가비지 수집기에 의해) 또는 나중에 (일부 운영 체제 스위핑 프로세스에 의해 ) 종료 될 수 있습니다 .



죄송합니다. docs.oracle.com/javase/6/docs/api/java/io/… 메소드 만 확인 했는데 답변이 없습니다. 긴 설명은 서명이 더 긴 메서드에만 있습니다.
Alphaaa

답변:


95

파일은 JavaDoc 에서 자동으로 삭제되지 않습니다 .

이 방법은 임시 파일 기능의 일부만 제공합니다. 이 메서드로 만든 파일을 자동으로 삭제하려면 deleteOnExit () 메서드를 사용합니다.

따라서 명시 적으로 deleteOnExit ()를 호출해야합니다 .

가상 머신이 종료 될 때이 추상 경로 이름으로 표시된 파일 또는 디렉토리를 삭제하도록 요청합니다.


2
그리고 deleteOnExit를 사용하면 "가상 머신이 종료 될 때 삭제됩니다. 파일 (또는 디렉토리)은 등록 된 역순으로 삭제됩니다. 삭제를 위해 이미 등록 된 파일 또는 디렉토리를 삭제하기 위해이 메소드를 호출하면 삭제는 Java 언어 사양에 정의 된대로 가상 머신의 정상적인 종료에 대해서만 시도됩니다. " 따라서 모든 JVM이 존재하더라도 삭제되지 않습니다.
eis

감사 합니다. 답을 제공하지 않는 docs.oracle.com/javase/6/docs/api/java/io/… 메소드 만 확인했습니다 . 긴 설명은 더 이상 서명 방법 만 존재
Alphaaa

52

다른 답변에서 알 수 있듯이로 만든 임시 파일 File.createTempFile()은 명시 적으로 요청하지 않는 한 자동으로 삭제 되지 않습니다 .

이 작업을 수행 할 수있는 일반적인 휴대용 방법은 호출하는 것입니다 .deleteOnExit()FileJVM이 종료 될 때 삭제 파일을 예약 할 객체. 그러나이 방법의 약간의 단점은 VM이 정상적으로 종료되는 경우에만 작동한다는 것입니다. 비정상 종료 (예 : VM 충돌 또는 VM 프로세스의 강제 종료)시 파일은 삭제되지 않은 상태로 남아있을 수 있습니다.

Unixish 시스템 (예 : Linux)에서는 임시 파일 을 연 후 즉시 삭제하여 좀 더 안정적인 솔루션을 얻을 수 있습니다 . 이것은 Unix 파일 시스템이 파일이 하나 이상의 프로세스에 의해 열린 상태로 유지되는 동안 삭제 ( 정확히 말하자면 unlinked )를 허용하기 때문에 작동 합니다. 이러한 파일은 열린 파일 핸들을 통해 정상적으로 액세스 할 수 있으며 디스크에서 차지하는 공간은 파일에 대한 열린 핸들을 보유한 마지막 프로세스가 종료 된 후에 만 ​​OS에 의해 회수됩니다.

따라서 프로그램이 종료 된 후 임시 파일이 제대로 삭제되도록하는 가장 안정적이고 이식 가능한 방법은 다음과 같습니다.

import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;

public class TempFileTest
{
    public static void main(String[] args)
    {
        try {
            // create a temp file
            File temp = File.createTempFile("tempfiletest", ".tmp"); 
            String path = temp.getAbsolutePath();
            System.err.println("Temp file created: " + path);

            // open a handle to it
            RandomAccessFile fh = new RandomAccessFile (temp, "rw");
            System.err.println("Temp file opened for random access.");

            // try to delete the file immediately
            boolean deleted = false;
            try {
                deleted = temp.delete();
            } catch (SecurityException e) {
                // ignore
            }

            // else delete the file when the program ends
            if (deleted) {
                System.err.println("Temp file deleted.");
            } else {
                temp.deleteOnExit();
                System.err.println("Temp file scheduled for deletion.");
            }

            try {
                // test writing data to the file
                String str = "A quick brown fox jumps over the lazy dog.";
                fh.writeUTF(str);
                System.err.println("Wrote: " + str);

                // test reading the data back from the file
                fh.seek(0);
                String out = fh.readUTF();
                System.err.println("Read: " + out);

            } finally {
                // close the file
                fh.close();
                System.err.println("Temp file closed.");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Unixish 시스템에서이를 실행하면 다음과 같은 출력이 생성됩니다.

Temp file created: /tmp/tempfiletest587200103465311579.tmp
Temp file opened for random access.
Temp file deleted.
Wrote: A quick brown fox jumps over the lazy dog.
Read: A quick brown fox jumps over the lazy dog.
Temp file closed.

반면 Windows에서는 출력이 약간 다르게 보입니다.

Temp file created: C:\DOCUME~1\User\LOCALS~1\Temp\tempfiletest5547070005699628548.tmp
Temp file opened for random access.
Temp file scheduled for deletion.
Wrote: A quick brown fox jumps over the lazy dog.
Read: A quick brown fox jumps over the lazy dog.
Temp file closed.

그러나 두 경우 모두 프로그램이 종료 된 후에 임시 파일이 디스크에 남아 있으면 안됩니다.


추신. Windows에서이 코드를 테스트하는 동안 다소 놀라운 사실을 발견했습니다 . 임시 파일을 닫지 않은 상태로 두는 것만으로도 삭제되는 것을 방지 할 수 있습니다 . 물론 이것은 임시 파일이 사용 중일 때 발생하는 모든 충돌로 인해 삭제되지 않은 상태로 남게되며, 이것이 바로 여기서 하려고하는 것임을 의미합니다 .

AFAIK,이를 방지하는 유일한 방법은 임시 파일이 항상finally 블록을 사용하여 닫히도록하는 것 입니다. 물론 같은 finally블록 에서 파일을 삭제할 수도 있습니다. 나는 무엇을 사용하는 .deleteOnExit()것이 실제로 당신을 얻는 것이 무엇인지 잘 모르겠습니다 .


1
좋은 대답입니다. 주의해야 할 또 다른 중요한 점 deleteOnExit()은 자주 호출되는 경우 (예 : 많은 새 임시 파일을 사용하는 시스템에서) 메모리 누수가 발생할 수 있다는 것입니다 (필요한 모든 경로를 기억해야하기 때문). 삭제됨).
Eyal Roth

18

delete()메서드를 명시 적으로 호출하지 않으면 언제 파일이 삭제됩니까?

적어도 Java에서는 그렇지 않습니다. JVM이 종료 될 때 파일을 삭제하려면을 호출해야합니다 tmp.deleteOnExit().


5

from : Java에서 임시 파일을 삭제하는 방법

임시 파일은 덜 중요하고 임시 데이터를 저장하는 데 사용되며 시스템 종료시 항상 삭제해야합니다 . 가장 좋은 방법은 File.deleteOnExit ()를 사용하는 것입니다.

예를 들면

File temp = File.createTempFile("abc", ".tmp"); 
temp.deleteOnExit();

위의 예는“abc.tmp”라는 임시 파일을 생성 하고 프로그램이 종료되거나 종료 될 때 삭제합니다 .

임시 파일을 수동으로 삭제 하려는 경우 에도 File.delete ()를 사용할 수 있습니다.


이것이 모범 사례 인 이유는 무엇입니까?
Frans

3

임시 파일은 덜 중요하고 임시 데이터를 저장하는 데 사용되며 시스템 종료시 항상 삭제해야합니다. 가장 좋은 방법은 File.deleteOnExit ()를 사용하는 것입니다.

예를 들면

File temp = File.createTempFile("abc", ".tmp"); 
temp.deleteOnExit();

위의 예는“abc.tmp”라는 임시 파일을 만들고 프로그램이 종료되거나 종료 될 때 삭제합니다.


-3

원할 경우 프로세스를 종료하기 전에 파일을 수동으로 삭제할 수 있지만 프로세스가 종료되면 파일도 삭제됩니다.


3
아니요, 특별히 전화 한 경우에만 deleteOnExit()
Ian Roberts
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.