2009-06-13 6 views
84

मैं कुछ लिखने के बाद फ़ाइल को हटाने का प्रयास कर रहा हूं इसमें FileOutputStream के साथ। इस कोड मैं लिखने के लिए उपयोग करते हैं:file.delete() फ़ाइल लौटता है भले ही file.exists(), file.canRead(), file.canWrite(), file.canExecute() सभी सही वापसी

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() आज़माएं और झूठी वापसी करता हूं।

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

+0

मुझे लगता है कि कोई अपवाद नहीं पकड़ा है उल्लेख करना भूल गया

यहाँ मेरी कोड है। –

+0

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

+0

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

उत्तर

44

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

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

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

मुझे BufferedReader और FileOutputStream को असंगत होने के बारे में पता नहीं है।

+4

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

+2

मुझे यह सही समस्या थी और मैंने सोचा कि मैं पागल हो रहा था। समाधान के लिए धन्यवाद! –

+13

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

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

यह OS X पर ठीक काम करता है मैं खिड़कियों पर यह परीक्षण नहीं किया लेकिन मैं यह विंडोज पर भी काम करना चाहिए संदेह है। मैं Windows w.r.t. पर कुछ अप्रत्याशित व्यवहार को भी स्वीकार कर दूंगा। फ़ाइल रखरखाव।

+1

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

3

जैसा कि जॉन स्कीट ने टिप्पणी की थी, आपको अंततः {...} ब्लॉक में अपनी फ़ाइल बंद करनी चाहिए ताकि यह सुनिश्चित किया जा सके कि यह हमेशा बंद रहता है। और, ई.प्रिंटस्टैकट्रेस के साथ अपवादों को निगलने के बजाय, बस पकड़ने और विधि हस्ताक्षर में अपवाद जोड़ें। आप नहीं किसी भी कारण से, कम से कम यह कर सकते हैं, तो:

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

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

+0

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

1

उम्मीद है कि इससे मदद मिलेगी। मैं इसी तरह की समस्या में आया जहां मेरे जावा कोड के बाद मैं अपनी फ़ाइल को अन्य फ़ोल्डर में कॉपी करने के बाद अपनी फ़ाइल को हटा नहीं सका। व्यापक googling के बाद, मैंने स्पष्ट रूप से प्रत्येक फ़ाइल ऑपरेशन से संबंधित चर घोषित किया और प्रत्येक फ़ाइल ऑपरेशन ऑब्जेक्ट की क्लोज़() विधि कहा, और उन्हें न्यूल पर सेट किया। फिर, 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(); 
    } 
} 
90

जावा में एक और बग:

यहाँ मेरी उदाहरण कोड है। मैं शायद ही कभी उन्हें अपने 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

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715154 – andreadi

+6

हालांकि मैंने इसे किसी भी प्रकार की स्ट्रीम के साथ नहीं खोल दिया (बस 'नई फ़ाइल (पथ)' कर रहा हूं), मुझे एक ही समस्या का सामना करना पड़ा और 'हटाएं') से पहले 'System.gc() 'जोड़कर यह काम करता है! – ixM

+1

अन्य बग क्या है? –

0

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

15

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

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

यह मेरे लिए काम करता है।

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

+1

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

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

ऊपर पाश का उपयोग करना आदि किसी भी मैनुअल कचरा एकत्र करने क्या करने वाले या अशक्त करने के लिए धारा की स्थापना, बिना काम किया

+0

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

+1

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

+0

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

2

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

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; 
} 
1

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

0

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

5

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

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

+0

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

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
ग्रहण के लिए

/NetBeans

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

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

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

आउटपुट::

हटाएँ

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^