Java geçici dosyaları ne zaman silinir?


92

Java'da şu yöntemle geçici bir dosya oluşturduğumu varsayalım

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

Ben explicity aramazsan delete()yöntemi, zaman dosya silinecektir?

Bir sezgi olarak, JVM sona erdiğinde veya daha önce (Çöp Toplayıcı tarafından) veya daha sonra (bazı İşletim Sistemi süpürme işlemleriyle) olabilir.



özür dilerim, sadece cevabı sağlamayan docs.oracle.com/javase/6/docs/api/java/io/… yöntemini kontrol ettim . Uzun açıklama sadece daha uzun imzalı yöntemde mevcuttur.
Alphaaa

Yanıtlar:


95

Dosya JavaDoc'tan otomatik olarak silinmeyecektir :

Bu yöntem, bir geçici dosya tesisinin yalnızca bir bölümünü sağlar. Bu yöntemle oluşturulan bir dosyanın otomatik olarak silinmesini düzenlemek için deleteOnExit () yöntemini kullanın.

Bu nedenle, deleteOnExit () ' i açıkça çağırmanız gerekir :

Bu soyut yol adıyla belirtilen dosya veya dizinin, sanal makine sona erdiğinde silinmesini ister.


2
ve deleteOnExit kullanılırsa, "sanal makine sona erdiğinde silinecektir. Dosyalar (veya dizinler), kaydedildikleri sıranın tersi sırayla silinir. Silme için önceden kaydedilmiş bir dosyayı veya dizini silmek için bu yöntemi çağırmak Etkisi. Silme işlemi, Java Dil Spesifikasyonu tarafından tanımlandığı gibi yalnızca sanal makinenin normal sonlandırılması için denenecektir. " bu nedenle tüm JVM'lerde bile silinmez.
eis

teşekkürler, sadece cevabı sağlamayan docs.oracle.com/javase/6/docs/api/java/io/… yöntemini kontrol ettim . Uzun açıklama yalnızca daha uzun imzaya sahip yöntemde mevcuttur
Alphaaa

52

Diğer cevaplar not olarak oluşturulan geçici dosyalar File.createTempFile()olacak değil açıkça istemedikçe otomatik olarak silinecektir.

Bunu yapmanın genel, taşınabilir yolu .deleteOnExit(), Filenesneyi çağırmaktır ; bu , JVM sona erdiğinde dosyayı silinmek üzere zamanlayacaktır. Bununla birlikte, bu yöntemin küçük bir dezavantajı, yalnızca VM normal şekilde sona erdiğinde işe yaramasıdır; anormal bir sonlandırmada (yani, bir VM çökmesi veya VM sürecinin zorunlu sonlandırılması), dosya silinmemiş kalabilir.

Unixish sistemlerinde (Linux gibi), geçici dosyayı açtıktan hemen sonra silerek biraz daha güvenilir bir çözüm elde etmek aslında mümkündür . Bu işe yarar çünkü Unix dosya sistemleri bir dosyanın bir veya daha fazla işlem tarafından açık tutulurken silinmesine ( kesin olarak bağlantısız) izin verir . Bu tür dosyalara normal olarak açık dosya tanıtıcısı aracılığıyla erişilebilir ve diskte kapladıkları alan, yalnızca dosya çıkışına açık bir tutamaç tutan son işlemden sonra işletim sistemi tarafından geri kazanılacaktır.

İşte programdan çıktıktan sonra geçici bir dosyanın düzgün şekilde silinmesini sağlamanın bildiğim en güvenilir ve taşınabilir yolu:

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();
        }
    }
}

Bir Unixish sisteminde, bunu çalıştırmak aşağıdaki çıktıya benzer bir şey üretmelidir:

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.

oysa Windows'ta çıktı biraz farklı görünüyor:

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.

Her iki durumda da, program bittikten sonra geçici dosya diskte kalmamalıdır.


Ps. Bu kodu Windows'ta test ederken oldukça şaşırtıcı bir gerçek gözlemledim: Görünüşe göre geçici dosyayı kapatmadan bırakmak, silinmesini önlemek için yeterli . Tabii ki, bu aynı zamanda geçici dosya kullanımdayken meydana gelen herhangi bir kilitlenmenin silinmemiş kalmasına neden olacağı anlamına gelir, bu da tam olarak burada kaçınmaya çalıştığımız şeydir .

AFAIK, bundan kaçınmanın tek yolu, geçici dosyanın her zaman bir finallyblok kullanılarak kapatılmasını sağlamaktır . Tabii ki, o zaman aynı finallybloktaki dosyayı da silebilirsiniz . Ne olursa olsun, kullanmanın .deleteOnExit()aslında bundan daha fazla kazanacağını bilmiyorum.


1
Mükemmel cevap. Dikkat edilmesi gereken bir diğer önemli nokta deleteOnExit()da, sık sık çağrılırsa (örneğin, çok sayıda yeni geçici dosya kullanan bir sistemde), muhtemelen bir bellek sızıntısına neden olacaktır (çünkü olması gereken tüm yolları ezberlemesi gerekir) silindi).
Eyal Roth

18

Ben explicity aramazsan delete()yöntemi, zaman dosya silinecektir?

En azından Java ile olmayacak. JVM sona erdiğinde dosyanın silinmesini istiyorsanız, aramanız gerekir tmp.deleteOnExit().


5

kaynak: Java'da geçici dosya nasıl silinir

Geçici dosya, sisteminiz sonlandırıldığında her zaman silinmesi gereken daha az önemli ve geçici verileri depolamak için kullanılır . En iyi uygulama, bunu yapmak için File.deleteOnExit () kullanmaktır.

Örneğin,

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

Yukarıdaki örnek, "abc.tmp" adında geçici bir dosya oluşturacak ve program sonlandırıldığında veya kapatıldığında bu dosyayı silecektir .

İsterseniz manuel geçici dosyayı silmek , hala File.delete kullanabilirsiniz ().


Bu neden en iyi uygulamadır?
Frans

3

Geçici dosya, sisteminiz sonlandırıldığında her zaman silinmesi gereken daha az önemli ve geçici verileri depolamak için kullanılır. En iyi uygulama, bunu yapmak için File.deleteOnExit () kullanmaktır.

Örneğin,

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

Yukarıdaki örnek, "abc.tmp" adında geçici bir dosya oluşturacak ve program sonlandırıldığında veya kapatıldığında onu silecektir.


-3

İsterseniz işlemi sonlandırmadan önce dosyayı manuel olarak silebilirsiniz, ancak işlem sonlandırıldığında dosya da silinecektir.


3
Hayır, yalnızca özel olarak ararsanız, çıkışta silinirdeleteOnExit()
Ian Roberts
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.