file.delete () भले ही गलत हो। हालांकि file.exists (), file.canRead (), file.canWrite (), file.canExecute () सभी सही हैं


90

मैं इसके साथ कुछ लिखने के बाद, एक फ़ाइल को हटाने की कोशिश कर रहा हूं 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()वह गलत हो जाता है।

मैं हटाए जाने से पहले जाँच की है, तो फ़ाइल मौजूद है को देखने के लिए, और: file.exists(), file.canRead(), file.canWrite(), file.canExecute()सभी वापसी सच। बस इन विधियों को कॉल करने के बाद मैं कोशिश करता हूं file.delete()और झूठे वापस करता हूं

क्या मैंने कुछ गलत किया है?


मैं यह उल्लेख करना भूल गया कि कोई अपवाद नहीं पकड़ा गया है।
जेनी स्मिथ

क्या आप सुनिश्चित हैं कि फ़ाइल किसी अन्य प्रक्रिया द्वारा उपयोग नहीं की गई है? क्या आपने इसे लॉक किया? क्या यह deleteOnExit + बाहर निकलने के साथ काम करता है?
उदाहरण मुझे

आप किस ओएस पर चल रहे हैं? क्या आप फ़ाइल को मैन्युअल रूप से हटा सकते हैं? कुछ फ़ाइल के लिए एक खुला हैंडल पकड़ सकता है।
एकरनोकद

यदि यह किसी अन्य प्रक्रिया द्वारा उपयोग किया जाता है, तो मुझे कैसे पता चलेगा? मैंने इसे लॉक नहीं किया। मैं डिलीटऑनस्टिट विधि का उपयोग नहीं कर सकता, क्योंकि मुझे फ़ाइल को हटाने की आवश्यकता है और उसके बाद अपना आवेदन जारी रखना होगा। विचार यह है कि मैं एक अस्थायी फ़ोल्डर का अनुकरण करने की कोशिश करता हूं, जिसका उपयोग एक सत्र के लिए अलग फ़ोल्डर से फ़ाइलों को संग्रहीत करने के लिए किया जाता है। जब मैं अपने आवेदन पर खुले बटन को दबाता हूं, तो इसका मतलब है कि फ़ोल्डर को खाली करना होगा, कुछ अन्य फ़ाइलों के लिए जगह बनाने के लिए। यदि मैं उस फ़ाइल में लिखते समय भाग छोड़ देता हूं, तो यह ठीक है, और मैं इसे हटा सकता हूं।
जेनी स्मिथ

1
क्या आप कृपया अपने फ्लश को लपेट सकते हैं और अंत में ब्लॉक कर सकते हैं? मुझे पता है कि आपने यह किया है और यह काम नहीं करता है, लेकिन यह आपके प्रश्न में स्पष्टता जोड़ देगा।
बरहल

जवाबों:


99

जावा में एक और बग। मैं शायद ही कभी उन्हें खोजता हूं, मेरे 10 साल के करियर में यह केवल दूसरा है। यह मेरा समाधान है, जैसा कि दूसरों ने उल्लेख किया है। मैं nether का इस्तेमाल किया है 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();
    }
}

7
हालाँकि मैंने इसे किसी भी प्रकार की धारा (सिर्फ एक new File(path)) के साथ नहीं खोला था , लेकिन मुझे उसी समस्या का सामना करना पड़ा और System.gc()इससे पहले कि delete()यह काम कर रहा था!
ixM

1
अन्य बग क्या है?
bogdan.mustiata

मेरे लिए नहीं करता है। जिस फ़ाइल को मैं हटा नहीं सकता, वह एक डाउनलोड की गई फ़ाइल का ज़िप फ़ाइल है। अच्छी बात यह है कि डाउनलोड की गई फ़ाइल हटा दी जाएगी। कोई उपाय?
एंड्रिया_86

मेरे लिए काम किया। और @andreadi मैंने अपने कोड में कभी FileChannel.map का इस्तेमाल नहीं किया। ऐसा लगता है कि इस बग को अनोलोवेबल के रूप में बंद कर दिया गया जो मुझे अविश्वसनीय बनाता है क्योंकि System.gcचाल हर बार काम करती है।
एडम बुर्ले

सिंगल gc () शायद मदद न करेSystem.gc(); result = file.delete(); if (!result){ Thread.sleep(100); System.gc(); result = file.delete(); }
jj

48

यह बहुत अजीब चाल थी जो काम करती थी। बात तब है जब मैंने पहले फ़ाइल की सामग्री को पढ़ा है, मैंने उपयोग किया है BufferedReader। पढ़ने के बाद, मैंने बफर को बंद कर दिया।

इस बीच मैंने स्विच किया और अब मैं सामग्री का उपयोग कर रहा हूं FileInputStream। इसके अलावा पढ़ने के बाद मैं धारा बंद कर देता हूं। और अब यह काम कर रहा है।

समस्या यह है कि मेरे पास इसके लिए स्पष्टीकरण नहीं है।

मैं नहीं जानता BufferedReaderऔर FileOutputStreamअसंगत होना।


4
मैं यह तर्क दूंगा कि यह एक बग है: java.sun.com/javase/6/docs/api/java/io/…। इसमें कहा गया है कि विधि को धारा और उससे जुड़े किसी भी संसाधन को बंद कर देना चाहिए। मैं आमतौर पर IOUtils.closeQuietly का उपयोग करके उल्टे अनुक्रम में सभी धाराओं को बंद करना चाहता हूं (पिछले वाले खुले होने वाले पहले बंद हैं), लेकिन यह ओवरकिल हो जाता है।
रवि वालौ

2
मुझे यह सटीक समस्या हो रही थी कि मुझे और मुझे लगा कि मैं पागल हो रहा हूं। समाधान के लिए धन्यवाद!
इलेक्ट्रॉन्स_अहॉय

14
यह JDK 7 के साथ 2011 है और समस्या अभी भी तय नहीं है। मुझे खुशी है कि मुझे यह धागा मिल गया - मैं बस यह पता नहीं लगा सका कि क्या गलत था ...
डेविड

मुझे एक फ़ाइल के साथ बहुत कष्टप्रद समस्या थी जिसे मैंने पढ़ा और बंद कर दिया और फिर हटाने की कोशिश की। यहां उल्लेखित कुछ भी मदद नहीं की। फिर एक घंटे के बाद मुझे पता चला कि यह केवल फ़ाइल अधिकार था, क्योंकि फ़ाइल किसी अन्य उपयोगकर्ता द्वारा बनाई गई थी :-D
रनहोलेन

अंधेरे में बस एक छुरा ... क्या आप finalize()सफाई सुनिश्चित करने के लिए कॉल कर सकते हैं ? या शायद सेट to = null? फोर्ज़िंग फाइनल और गारबेज कलेक्शन देखें ।
jww

19

मैंने इस सरल चीज़ की कोशिश की और यह काम करने लगता है।

file.setWritable(true);
file.delete();

इससे मेरा काम बनता है।

अगर यह काम नहीं करता है तो अपने जावा एप्लिकेशन को सूडो के साथ चलाने की कोशिश करें यदि लिनक्स पर और खिड़कियों पर व्यवस्थापक के रूप में। बस यह सुनिश्चित करने के लिए कि जावा के पास फ़ाइल गुण बदलने के अधिकार हैं।


1
इस समस्या के लिए; आमतौर पर लोग संदर्भों को अशक्त या कॉलिंग सिस्टम के रूप में सेट करने की बात करते हैं। gc (); लेकिन सर्वर पुनरारंभ के बाद भी मेरे लिए फ़ाइलें नष्ट नहीं हो रही थीं !! लेकिन file.setWritable (सच); बस काम किया ..
दीपक सिंघल

6

किसी भी फ़ाइल को हटाने / नाम बदलने की कोशिश करने से पहले, आपको यह सुनिश्चित करना होगा कि सभी पाठक या लेखक (उदा: BufferedReader/ InputStreamReader/ BufferedWriter) ठीक से बंद हैं।

जब आप किसी फ़ाइल से / से अपने डेटा को पढ़ने / लिखने की कोशिश करते हैं, तो फ़ाइल को प्रक्रिया द्वारा पकड़ लिया जाता है और तब तक जारी नहीं किया जाता है जब तक कि प्रोग्राम निष्पादन पूरा नहीं हो जाता है। यदि आप कार्यक्रम समाप्त होने से पहले डिलीट / नाम बदलना चाहते हैं, तो आपको कक्षाओं के close()साथ आने वाली विधि का उपयोग करना होगा java.io.*


1
यह केवल विंडोज पर सच है। किसी भी वास्तविक O / S पर आप खुली फ़ाइलों को हटा सकते हैं और उनका नाम बदल सकते हैं।
आर्ची

3

जैसा कि जॉन स्कीट ने टिप्पणी की, आपको अपनी फ़ाइल को अंत में {...} ब्लॉक करना चाहिए, यह सुनिश्चित करने के लिए कि यह हमेशा बंद है। और, 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 (...) का उपयोग करता हूं, इसलिए मैं फ्लश विधि का उपयोग यह सुनिश्चित करने के लिए करता हूं कि फ़ाइल की सामग्री वहां है इससे पहले कि मैं इसे बंद करने की कोशिश करूं (IOUtils.closeQuietly अपवादों को फेंक नहीं देता)। कुछ इस तरह:

...
try {
    ...
    to.flush();
} catch(IOException ex) {
    throw new CannotProcessFileException("whatever", ex);
} finally {
    IOUtils.closeQuietly(to);
}

तो मुझे पता है कि फ़ाइल की सामग्री वहाँ है। जैसा कि यह आमतौर पर मेरे लिए मायने रखता है कि फ़ाइल की सामग्री लिखी गई है और नहीं कि फ़ाइल बंद हो सकती है या नहीं, यह वास्तव में कोई फर्क नहीं पड़ता कि फ़ाइल बंद थी या नहीं। आपके मामले में, जैसा कि यह मायने रखता है, मैं फ़ाइल को स्वयं बंद करने और उसके अनुसार किसी भी अपवाद का इलाज करने की सलाह दूंगा।


मैंने पहली चीज की कोशिश की - आखिर में ब्लॉक में आउटपुट स्ट्रीम को बंद करना। और यह काम नहीं किया। अगर मैंने उसके बाद पढ़ने की कोशिश की तो क्या हुआ कि मुझे एक संदेश मिला जिसमें कहा गया था कि धारा बंद हो गई है। FileInputReader के साथ फ़ाइल को स्विच और रीड करते समय, ऊपर वर्णित "खराब" चीज़ों में से कोई भी नहीं हुआ।
जेनी स्मिथ

2

कोई कारण नहीं है कि आप इस फ़ाइल को हटाने में सक्षम नहीं होना चाहिए। मैं देखना चाहूंगा कि इस फाइल पर किसकी पकड़ है। यूनिक्स / लिनक्स में, आप यह जांचने के लिए lsof उपयोगिता का उपयोग कर सकते हैं कि किस प्रक्रिया में फ़ाइल पर ताला है। खिड़कियों में, आप प्रक्रिया एक्सप्लोरर का उपयोग कर सकते हैं।

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

यह ओएस एक्स पर ठीक काम करता है। मैंने इसे खिड़कियों पर परीक्षण नहीं किया है, लेकिन मुझे संदेह है कि इसे विंडोज पर भी काम करना चाहिए। मैं भी विंडोज अप्रत्याशित फ़ाइल हैंडलिंग पर कुछ अप्रत्याशित व्यवहार को देख रहा हूँ।


1
विंडोज़ के लिए, आप MS से मुफ्त प्रोसेस एक्सप्लोरर डाउनलोड कर सकते हैं: Technet.microsoft.com/en-us/sysinternals/bb896653.aspx
akarnokd

2

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


1

उम्मीद है कि इससे मदद मिलेगी। मुझे इसी तरह की समस्या सामने आई, जहाँ मैं अपने फाइल को डिलीट नहीं कर सकता था क्योंकि मेरे जावा कोड ने अन्य फ़ोल्डर में सामग्री की प्रतिलिपि बनाई थी। व्यापक googling के बाद, मैंने स्पष्ट रूप से हर एक फ़ाइल ऑपरेशन संबंधित चर घोषित किया और प्रत्येक फ़ाइल ऑपरेशन ऑब्जेक्ट के करीब () विधि कहा, और उन्हें NULL पर सेट किया। फिर, System.gc () नामक एक फ़ंक्शन है, जो फ़ाइल i / o मैपिंग को स्पष्ट करेगा (मुझे यकीन नहीं है, मैं सिर्फ यह बताता हूं कि वेब साइटों पर क्या दिया गया है)।

यहाँ मेरा उदाहरण कोड है:

public void start() {
    File f = new File(this.archivePath + "\\" + this.currentFile.getName());
    this.Copy(this.currentFile, f);

    if(!this.currentFile.canWrite()){
        System.out.println("Write protected file " +
           this.currentFile.getAbsolutePath());

        return;
    }


    boolean ok = this.currentFile.delete();
    if(ok == false){
        System.out.println("Failed to remove " + this.currentFile.getAbsolutePath());
        return;
    }
}

private void Copy(File source, File dest) throws IOException {
    FileInputStream fin;
    FileOutputStream fout;
    FileChannel cin = null, cout = null;
    try {
        fin = new FileInputStream(source);
        cin = fin.getChannel();
        fout = new FileOutputStream(dest);
        cout = fout.getChannel();

        long size = cin.size();
        MappedByteBuffer buf = cin.map(FileChannel.MapMode.READ_ONLY, 0, size);

        cout.write(buf);
        buf.clear();
        buf = null;

        cin.close();
        cin = null;

        fin.close();
        fin = null;

        cout.close();
        cout = null;

        fout.close();
        fout = null;

        System.gc();

    } catch (Exception e){
        this.message = e.getMessage();
        e.printStackTrace();
    }
}

1

जब आप फ़ाइल को लोड करते हैं, तो आपको कोड के किसी भी लाइन में "क्लोज़" पद्धति लागू करने की आवश्यकता होती है


0

रूबी में एक बार एक समस्या थी जहां खिड़कियों में फ़ाइलों को "fsync" की आवश्यकता होती थी, वास्तव में इसे चालू करने और इसे बंद करने के बाद फ़ाइल को फिर से पढ़ने और फिर से पढ़ने में सक्षम होना चाहिए। शायद यह एक समान अभिव्यक्ति है (और यदि हां, तो मुझे लगता है कि विंडोज़ बग, वास्तव में)।


0

यहां सूचीबद्ध समाधानों में से किसी ने भी मेरी स्थिति में काम नहीं किया। सुरक्षा के लिए 5 सेकंड (कॉन्फ़िगर करने योग्य) सीमा के साथ, फ़ाइल को हटाने का प्रयास करते हुए मेरा समाधान कुछ समय लूप का उपयोग करना था।

File f = new File("/path/to/file");

int limit = 20; //Only try for 5 seconds, for safety
while(!f.delete() && limit > 0){
    synchronized(this){
        try {
            this.wait(250); //Wait for 250 milliseconds
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    limit--;
}

उपर्युक्त लूप का उपयोग करके बिना किसी मैनुअल कचरा इकट्ठा करने या धारा को अशक्त करने के लिए, आदि के बिना काम किया।


तो आप क्या उपयोग करते हैं? यदि आप STREAMS तक पहुँच सकते हैं, तो उन्हें बंद करें, यह काम करेगा। लेकिन अगर फ़ाइल "पहले से ही" लॉक है, तो, आपको एक समस्या है।
मार्कोलोप्स

1
फ़ाइल को हटाने के लिए अपने कोड में -1 लूपिंग करना एक अच्छा विचार नहीं है। सिर्फ जीसी () विकल्प का उपयोग क्यों नहीं करता है जो काम करता है?
भावल

@ भार नोटिस मैं ऊपर बताता हूं कि मेरे विशेष मामले में अन्य समाधानों में से कोई भी (जीसी (सहित)) काम नहीं किया। जबकि मैं सहमत हूँ कि थोड़ी देर का उपयोग करना आदर्श नहीं है, यह कुछ विशेष परिस्थितियों में एक उपयुक्त समाधान हो सकता है। ऊपर दिए गए कोड में अतिरिक्त चेक जोड़ना, जैसे कि टाइमआउट या अधिकतम पुनरावृत्तियों चर, जबकि लूप को सुरक्षित बनाने के लिए एक अच्छा तरीका होगा।
etech

@etech अगर आपकी फ़ाइल कभी अस्तित्व में नहीं है, तो आपने सिर्फ एक अनंत लूप बनाया है।
बरहल

0

समस्या यह हो सकती है कि फ़ाइल को अभी भी एक प्रोग्राम द्वारा खोले और लॉक के रूप में देखा जाता है; या हो सकता है कि यह आपके प्रोग्राम से एक घटक है जिसे इसे खोला गया था, इसलिए आपको यह सुनिश्चित करना होगा कि आप dispose()उस समस्या को हल करने के लिए विधि का उपयोग करें । अर्थातJFrame frame; .... frame.dispose();


0

आपको सभी स्ट्रीम को बंद करना होगा या कोशिश-के-संसाधन ब्लॉक का उपयोग करना होगा

static public String head(File file) throws FileNotFoundException, UnsupportedEncodingException, IOException
{
    final String readLine;
    try (FileInputStream fis = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
            LineNumberReader lnr = new LineNumberReader(isr))
    {
        readLine = lnr.readLine();
    }
    return readLine;
}

0

अगर file.delete () गलत भेज रहा है, तो ज्यादातर मामलों में आपका बफ़रेड्रेडर हैंडल बंद नहीं होगा। बस करीब है और यह मेरे लिए सामान्य रूप से काम करने लगता है।


0

मुझे विंडोज पर भी यही समस्या थी। मैं स्कैला लाइन में फ़ाइल को लाइन से पढ़ता था

Source.fromFile(path).getLines()

अब मैंने इसे पूरे के साथ पढ़ा

import org.apache.commons.io.FileUtils._

// encoding is null for platform default
val content=readFileToString(new File(path),null.asInstanceOf[String])

जो पढ़ने के बाद और अब फ़ाइल को ठीक से बंद कर देता है

new File(path).delete

काम करता है।


0

ग्रहण / नेटबीन्स के लिए

अपनी IDE को पुनरारंभ करें और अपना कोड फिर से चलाएं यह केवल एक घंटे के लंबे संघर्ष के बाद मेरे लिए चाल का काम है।

यहाँ मेरा कोड है:

File file = new File("file-path");
if(file.exists()){
  if(file.delete()){
     System.out.println("Delete");
  }
  else{

       System.out.println("not delete");
  }
}

आउटपुट:

हटाएं


0

एक और कोने का मामला जो यह हो सकता है: यदि आप एक JAR फ़ाइल को एक के माध्यम से पढ़ते / लिखते हैं URLऔर बाद में उसी JVM सत्र में उसी फ़ाइल को हटाने का प्रयास करते हैं।

File f = new File("/tmp/foo.jar");
URL j = f.toURI().toURL();

URL u = new URL("jar:" + j + "!/META-INF/MANIFEST.MF");
URLConnection c = u.openConnection();

// open a Jar entry in auto-closing manner
try (InputStream i = c.getInputStream()) {

    // just read some stuff; for demonstration purposes only
    byte[] first16 = new byte[16];
    i.read(first16);
    System.out.println(new String(first16));
}

// ...

// i is now closed, so we should be good to delete the jar; but...
System.out.println(f.delete());     // says false!

कारण यह है कि जावा की आंतरिक JAR फ़ाइल हैंडलिंग लॉजिक, JarFileप्रविष्टियों को कैश करता है :

// inner class of `JarURLConnection` that wraps the actual stream returned by `getInputStream()`

class JarURLInputStream extends FilterInputStream {
    JarURLInputStream(InputStream var2) {
        super(var2);
    }

    public void close() throws IOException {
        try {
            super.close();
        } finally {

            // if `getUseCaches()` is set, `jarFile` won't get closed!

            if (!JarURLConnection.this.getUseCaches()) {
                JarURLConnection.this.jarFile.close();
            }
        }
    }
}

और प्रत्येक JarFile(बल्कि, अंतर्निहित ZipFileसंरचना) फ़ाइल के लिए एक हैंडल पकड़, निर्माण के समय से सही है जब तक close()लागू किया गया है:

public ZipFile(File file, int mode, Charset charset) throws IOException {
    // ...

    jzfile = open(name, mode, file.lastModified(), usemmap);

    // ...
}

// ...

private static native long open(String name, int mode, long lastModified,
                                boolean usemmap) throws IOException;

इस NetBeans मुद्दे पर एक अच्छी व्याख्या है ।


जाहिरा तौर पर इसे "ठीक" करने के दो तरीके हैं:

  • आप JAR फ़ाइल कैशिंग को निष्क्रिय कर सकते हैं - वर्तमान के लिए URLConnection, या URLConnectionवर्तमान JVM सत्र में भविष्य के सभी (विश्व स्तर पर) के लिए:

    URL u = new URL("jar:" + j + "!/META-INF/MANIFEST.MF");
    URLConnection c = u.openConnection();
    
    // for only c
    c.setUseCaches(false);
    
    // globally; for some reason this method is not static,
    // so we still need to access it through a URLConnection instance :(
    c.setDefaultUseCaches(false);
  • [हैकिंग!]JarFile जब आप इसके साथ कर रहे हैं तो आप कैश से मैन्युअल रूप से शुद्ध कर सकते हैं। कैश प्रबंधक sun.net.www.protocol.jar.JarFileFactoryपैकेज-निजी है, लेकिन कुछ प्रतिबिंब जादू आपके लिए काम कर सकते हैं:

    class JarBridge {
    
        static void closeJar(URL url) throws Exception {
    
            // JarFileFactory jarFactory = JarFileFactory.getInstance();
            Class<?> jarFactoryClazz = Class.forName("sun.net.www.protocol.jar.JarFileFactory");
            Method getInstance = jarFactoryClazz.getMethod("getInstance");
            getInstance.setAccessible(true);
            Object jarFactory = getInstance.invoke(jarFactoryClazz);
    
            // JarFile jarFile = jarFactory.get(url);
            Method get = jarFactoryClazz.getMethod("get", URL.class);
            get.setAccessible(true);
            Object jarFile = get.invoke(jarFactory, url);
    
            // jarFactory.close(jarFile);
            Method close = jarFactoryClazz.getMethod("close", JarFile.class);
            close.setAccessible(true);
            //noinspection JavaReflectionInvocation
            close.invoke(jarFactory, jarFile);
    
            // jarFile.close();
            ((JarFile) jarFile).close();
        }
    }
    
    // and in your code:
    
    // i is now closed, so we should be good to delete the jar
    JarBridge.closeJar(j);
    System.out.println(f.delete());     // says true, phew.

कृपया ध्यान दें: यह सब जावा 8 कोडबेस ( 1.8.0_144) पर आधारित है ; वे अन्य / बाद के संस्करणों के साथ काम नहीं कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.