java - BufferedWriter अपनी आउटपुट फ़ाइल में सब कुछ नहीं लिख रहा है




file-io (6)

मेरे पास एक जावा प्रोग्राम है जो फ़ाइल से कुछ पाठ पढ़ता है, लाइन से लाइन करता है, और आउटपुट फ़ाइल में नया टेक्स्ट लिखता है। लेकिन प्रोग्राम के समाप्त होने के बाद आउटपुट फाइल में मेरे BufferedWriter को जो भी पाठ लिखा गया है, वह नहीं है। ऐसा क्यों है?

विवरण: कार्यक्रम एक CSV टेक्स्ट दस्तावेज़ लेता है और डेटा को तालिका में डालने के लिए इसे SQL कमांड में परिवर्तित करता है। टेक्स्ट फ़ाइल में 10000 से अधिक लाइनें हैं जो निम्न के जैसा दिखती हैं:

2007,10,9,1,1,1006134,19423882

कार्यक्रम ठीक काम करता प्रतीत होता है सिवाय इसके कि यह फ़ाइल में SQL सर्वर में मुद्रित एक नया SQL कथन बनाने के माध्यम से यादृच्छिक रूप से आधे रास्ते में बंद हो जाता है। ऐसा कुछ दिखता है:

insert into nyccrash values (2007, 1, 2, 1, 4, 1033092, 259916);
insert into nyccrash values (2007, 1, 1, 1, 1, 1020246, 197687);
insert into nyccrash values (2007, 10, 9, 1

यह लगभग 10000 लाइनों के बाद होता है लेकिन फ़ाइल के अंत से पहले कई सौ लाइनें होती हैं। जहां ब्रेक होता है 1 और ए के बीच होता है। हालांकि, पात्र महत्वपूर्ण नहीं लगते हैं क्योंकि यदि मैं 1 से 42 में बदलता हूं तो नई फ़ाइल में लिखी गई आखिरी चीज 4 , जो उस पूर्णांक से 2 को काट रही है। तो ऐसा लगता है कि पाठक या लेखक को निश्चित राशि लिखने / पढ़ने के बाद ही मरना चाहिए।

मेरा जावा कोड निम्नानुसार है:

import java.io.*;

public class InsertCrashData
{
    public static void main (String args[])
    {
        try
        {   
            //Open the input file.
            FileReader istream = new FileReader("nyccrash.txt");
            BufferedReader in = new BufferedReader(istream);
            //Open the output file.
            FileWriter ostream = new FileWriter("nyccrash.sql");
            BufferedWriter out = new BufferedWriter(ostream);
            String line, sqlstr;

            sqlstr = "CREATE TABLE nyccrash (crash_year integer, accident_type integer, collision_type integer, weather_condition integer, light_condition integer, x_coordinate integer, y_coordinate integer);\n\n"; 
            out.write(sqlstr);

            while((line = in.readLine())!= null)
            {
                String[] esa = line.split(",");
                sqlstr = "insert into nyccrash values ("+esa[0]+", "+esa[1]+", "+esa[2]+", "+esa[3]+", "+esa[4]+", "+esa[5]+", "+esa[6]+");\n";
                out.write(sqlstr);
            }
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
}

एक संसाधन जो बंद होना चाहिए जब इसकी आवश्यकता नहीं है।

finally {
    out.close();//this would resolve the issue
    }

विचार करने के लिए कुछ चीजें:

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

इसलिए, जब आप उनके साथ काम करते हैं तो हमेशा अपने संसाधनों को बंद करें (केवल फाइलें नहीं)।

यदि आप वास्तव में कवर के नीचे एक झांक चाहते हैं, तो जावा एपीआई का अधिकांश स्रोत उपलब्ध है। BufferedWriter here


आप अपने BufferedWriter को बंद कर दें। अंत में ब्लॉक के अंदर इसे बंद करें

   finally {
    out.close();//this would resolve the issue
    }

आपको अपना OutputStream बंद करना होगा जो आपके शेष डेटा को फ्लश करेगा:

out.close();

BufferedWriter लिए डिफ़ॉल्ट बफर आकार 8192 वर्ण है , जो आसानी से अनचाहे डेटा की सैकड़ों लाइनों को पकड़ने के लिए पर्याप्त है।


आपको अपने BufferedWriter को close() करना होगा close() । आपको अपने BufferedWriter को close() करना होगा क्योंकि यह IS-A Writer और इस प्रकार AutoCloseable लागू करता है, जिसका अर्थ है (जोर जोड़ा गया) यह है

एक संसाधन जो बंद होना चाहिए जब इसकी आवश्यकता नहीं है।

कुछ लोग कहते हैं कि आपको पहले flush() को कॉल करने से पहले अपने BufferedWriter लिए flush() को कॉल करना होगा। वे गलत हैं। BufferedWriter.close() लिए प्रलेखन नोट करता है कि यह "स्ट्रीम बंद करता है, इसे पहले फ़्लश करता है " (जोर जोड़ा गया)।

फ्लशिंग ( flush() ) के दस्तावेजबद्ध अर्थशास्त्र हैं

अंतर्निहित धारा में किसी भी buffered आउटपुट लिखकर इस धारा को फ्लश करें

तो, आपको close करना होगा, और close किसी भी buffered आउटपुट फ्लश होगा।

आपकी आउटपुट फ़ाइल में आपके BufferedWriter को लिखे गए सभी पाठ शामिल नहीं हैं क्योंकि यह उस पाठ में से कुछ को बफर में संग्रहीत करता है। BufferedWriter कभी भी उस बफर को खाली नहीं किया, इसे फ़ाइल में BufferedWriter दिया, क्योंकि आपने इसे ऐसा करने के लिए कभी नहीं बताया था।

चूंकि जावा 7 के बाद से, एक AutoCloseable संसाधन, जैसे कि BufferedWriter , को सुनिश्चित करने का सबसे अच्छा तरीका बंद हो जाता है, जब इसे स्वचालित संसाधन प्रबंधन (एआरएम) का उपयोग करने की आवश्यकता नहीं होती है, जिसे try-with-resources रूप में भी जाना जाता है:

 try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) {
    // writes to out here
 } catch (IOException ex) {
    // handle ex
 }

जब आपको इसकी आवश्यकता नहीं होती है तो आपको अपने BufferedReader को भी close करना होगा, इसलिए आपको संसाधनों के साथ-साथ संसाधनों को घोंसला करना चाहिए था:

 try (BufferedReader in = new BufferedReader(new FileReader("nyccrash.txt")) {
    try (BufferedWriter out = new BufferedWriter(new FileWriter("nyccrash.sql"))) {
       // your reading and writing code here
    }
 } catch (IOException ex) {
    // handle ex
 }

जब आप उनके साथ काम करते हैं तो हमेशा अपने संसाधनों को बंद करें (केवल फाइलें नहीं)।

 finally {
    out.close();//this would resolve the issue
    }

ऐसी स्थिति हो सकती है जब आप फ़ाइल को बंद किए बिना बफर को फ़्लश करना चाहते हैं। इन परिस्थितियों में आप फ्लश-विधि का उपयोग कर सकते हैं।


लिखने के बाद आपका कोड लेखक को बंद नहीं कर रहा है। एक out.close() (अधिमानतः अंत में ब्लॉक में) जोड़ें और इसे ठीक से काम करना चाहिए।





bufferedwriter