जावा अस्थायी फ़ाइलों को कब हटाया जाता है?


92

मान लीजिए कि मैं विधि के साथ जावा में एक अस्थायी फ़ाइल बनाता हूं

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

अगर मैं एक्सप्लिसिटी को delete()विधि नहीं कहता हूं , तो फ़ाइल को कब हटाया जाएगा?

एक अंतर्ज्ञान के रूप में, यह तब हो सकता है जब जेवीएम समाप्त हो जाता है, या पहले (कचरा कलेक्टर द्वारा), या बाद में (कुछ ऑपरेटिंग सिस्टम स्वीपिंग प्रक्रिया द्वारा)।



मेरी क्षमा याचना, मैंने केवल विधि की जाँच की docs.oracle.com/javase/6/docs/api/java/io/… , जो उत्तर प्रदान नहीं करता है। लंबा विवरण केवल लंबे हस्ताक्षर के साथ विधि में मौजूद है।
अल्फा

जवाबों:


95

JavaDoc से फ़ाइल स्वचालित रूप से नहीं हटाई जाएगी :

यह विधि एक अस्थायी फ़ाइल सुविधा का केवल एक भाग प्रदान करती है। स्वचालित रूप से हटाए जाने के लिए इस पद्धति द्वारा बनाई गई फ़ाइल की व्यवस्था करने के लिए, डिलीटऑनस्टिट () विधि का उपयोग करें।

तो आपको स्पष्ट रूप से DeleteOnExit () को कॉल करना होगा :

वर्चुअल मशीन के समाप्त होने पर इस सार पथनाम द्वारा निरूपित फ़ाइल या निर्देशिका को हटा दिया जाता है।


2
और अगर deleteOnExit का उपयोग किया जाता है, तो इसे हटा दिया जाएगा "जब वर्चुअल मशीन समाप्त हो जाती है। फ़ाइलों (या निर्देशिकाओं) को रिवर्स ऑर्डर में हटा दिया जाता है जो वे पंजीकृत हैं। किसी फ़ाइल या निर्देशिका को हटाने के लिए इस विधि को लागू करना जो पहले से ही विलोपन के लिए पंजीकृत है। प्रभाव। विलोपन का प्रयास केवल वर्चुअल मशीन की सामान्य समाप्ति के लिए किया जाएगा, जैसा कि जावा भाषा विनिर्देश द्वारा परिभाषित किया गया है। " इसलिए यह JVM मौजूद होने पर भी डिलीट नहीं होता है।
EIS

धन्यवाद, मैंने केवल विधि की जाँच की docs.oracle.com/javase/6/docs/api/java/io/… , जो उत्तर प्रदान नहीं करता है। लंबा विवरण केवल लंबे हस्ताक्षर के साथ विधि में मौजूद है
अल्फा

52

अन्य उत्तर ध्यान दें के रूप में, के साथ बनाया अस्थायी फ़ाइलें File.createTempFile()जाएगा नहीं अपने आप हटा दिया जब तक आप स्पष्ट यह अनुरोध करते हैं।

ऐसा करने का सामान्य, पोर्टेबल तरीका ऑब्जेक्ट .deleteOnExit()पर कॉल करना Fileहै, जो जेवीएम समाप्त होने पर विलोपन के लिए फाइल शेड्यूल करेगा। इस पद्धति का एक मामूली नुकसान, हालांकि, यह केवल तभी काम करता है जब वीएम सामान्य रूप से समाप्त हो जाता है; एक असामान्य समाप्ति पर (यानी एक वीएम क्रैश या वीएम प्रक्रिया की मजबूर समाप्ति), फ़ाइल अनिर्धारित रह सकती है।

यूनिक्स सिस्टम (जैसे लिनक्स) पर, खोलने के तुरंत बाद अस्थायी फ़ाइल को हटाकर कुछ हद तक अधिक विश्वसनीय समाधान प्राप्त करना संभव है । यह काम करता है क्योंकि यूनिक्स फाइल सिस्टम एक फाइल को हटाने की अनुमति देता है ( अनलिंक किया गया , सटीक होने के लिए) जबकि यह अभी भी एक या अधिक प्रक्रियाओं द्वारा खुला रखा गया है। इस तरह की फाइलें खुले फाइलहैंडल के माध्यम से सामान्य रूप से एक्सेस की जा सकती हैं, और डिस्क पर वे जिस स्थान पर कब्जा करते हैं, उसे अंतिम प्रक्रिया के बाद केवल ओएस द्वारा पुनर्प्राप्त किया जाएगा।

इसलिए यहां सबसे विश्वसनीय और पोर्टेबल तरीका है जो मुझे यह सुनिश्चित करने के लिए पता है कि कार्यक्रम से बाहर निकलने के बाद एक अस्थायी फ़ाइल को ठीक से हटा दिया जाएगा:

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.

विंडोज पर रहते हुए, आउटपुट थोड़ा अलग दिखता है:

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.

किसी भी स्थिति में, हालांकि, प्रोग्राम समाप्त होने के बाद अस्थायी फ़ाइल डिस्क पर नहीं रहनी चाहिए।


Ps। विंडोज पर इस कोड का परीक्षण करते समय, मैंने एक आश्चर्यजनक तथ्य देखा: जाहिरा तौर पर, केवल अस्थायी फाइल को छोड़ दिया गया , इसे हटाए जाने के लिए पर्याप्त है । बेशक, इसका मतलब यह भी है कि अस्थायी फ़ाइल के उपयोग के दौरान होने वाली कोई भी दुर्घटना इसे बिना छोड़े छोड़ दिया जाएगा, यही वह है जो हम यहां से बचने की कोशिश कर रहे हैं।

AFAIK, इससे बचने का एकमात्र तरीका यह सुनिश्चित करना है कि अस्थायी फ़ाइल हमेशा एक finallyब्लॉक का उपयोग करके बंद हो जाती है । बेशक, तब आप फ़ाइल को उसी finallyब्लॉक में भी डिलीट कर सकते हैं। मुझे यकीन नहीं है कि क्या, अगर कुछ भी, .deleteOnExit()वास्तव में आप उस पर लाभ होगा।


1
बहुत बढ़िया जवाब। एक और महत्वपूर्ण बात जो ध्यान रखने वाली है deleteOnExit(), वह यह है कि यदि इसे बार-बार कहा जाता है (एक प्रणाली में, जो बहुत सी नई अस्थायी फ़ाइलों का उपयोग करती है), तो यह संभवतः एक मेमोरी लीक का कारण बनेगी (क्योंकि इसमें उन सभी रास्तों को याद रखना होगा, जिनकी आवश्यकता है हटाया गया)।
इयाल रोथ

18

अगर मैं एक्सप्लिसिटी को delete()विधि नहीं कहता हूं , तो फ़ाइल को कब हटाया जाएगा?

यह कम से कम जावा द्वारा नहीं होगा। यदि आप चाहते हैं कि जेवीएम समाप्त होने पर फ़ाइल को हटा दिया जाए तो आपको कॉल करने की आवश्यकता है tmp.deleteOnExit()


5

से: जावा में अस्थायी फ़ाइल को कैसे हटाएं

अस्थायी फ़ाइल का उपयोग कम महत्वपूर्ण और अस्थायी डेटा को संग्रहीत करने के लिए किया जाता है, जिसे आपके सिस्टम के समाप्त होने पर हमेशा हटा दिया जाना चाहिए । सबसे अच्छा अभ्यास यह करने के लिए 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()
इयान रॉबर्ट्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.