سؤال

For some reason my String is written partially by PrintWriter. As a result I am getting partial text in my file. Here's the method:

    public void new_file_with_text(String text, String fname) {
        File f = null;
        try {
            f = new File(fname);
            f.createNewFile();
            System.out.println(text);           
            PrintWriter out = new PrintWriter(f, "UTF-8");
            out.print(text);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Where I print text to a console, I can see that the data is all there, nothing is lost, but apparently part of text is lost when PrintWriter does its job... I am clueless..

هل كانت مفيدة؟

المحلول

You should always Writer#close your streams before you discard your opened streams. This will free some rather expensive system resources that your JVM must quire when opening a file on the file system. If you do not want to close your stream, you can use Writer#flush. This will make your changes visible on the file system without closing the stream. When closing the stream, all data is flushed implicitly.

Streams always buffer data in order to only write to the file system when there is enough data to be written. The stream flushes its data automatically every now and then when it in some way considers the data worth writing. Writing to the file system is an expensive operation (it costs time and system resources) and should therefore only be done if it really is necessary. Therefore, you need to flush your stream's cache manually, if you desire an immediate write.

In general, make sure that you always close streams since they use quite some system resources. Java has some mechanisms for closing streams on garbage collection but these mechanisms should only be seen as a last resort since streams can live for quite some time before they are actually garbage collected. Therefore, always use try {} finally {} to assure that streams get closed, even on exceptions after the opening of a stream. If you do not pay attention to this, you will end up with an IOException signaling that you have opened too many files.

You want to change your code like this:

public void new_file_with_text(String text, String fname) {
    File f = null;
    try {
        f = new File(fname);
        f.createNewFile();
        System.out.println(text);           
        PrintWriter out = new PrintWriter(f, "UTF-8");
        try {
            out.print(text);
        } finally {
            out.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

نصائح أخرى

Try to use out.flush(); right after the line out.print(text);

Here is a proper way to write in a file :

public void new_file_with_text(String text, String fname) {
    try (FileWriter f = new FileWriter(fname)) {
        f.write(text);
        f.flush();
    } catch (IOException e) {
       e.printStackTrace();
    }
}

I tested you code. You forgot to close the PrintWriter object i.e out.close

try {
        f = new File(fname);
        f.createNewFile();
        System.out.println(text);           
        PrintWriter out = new PrintWriter(f, "UTF-8");
        out.print(text);
        out.close(); // <--------------
    } catch (IOException e) {
        System.out.println(e);
    }

You must always close your streams (which will also flush them), in a finally block, or using the Java 7 try-with-resources facility:

PrintWriter out = null;
try {
    ...
}
finally {
    if (out != null) {
        out.close();
    }
}

or

try (PrintWriter out = new PrintWriter(...)) {
    ...
}

If you don't close your streams, not only won't everything be flushed to the file, but at some time, your OS will be out of available file descriptors.

You should close your file:

PrintWriter out = new PrintWriter(f, "UTF-8");
try
{
        out.print(text);
}
finally
{
    try
    {
        out.close();
    }
    catch(Throwable t)
    {
        t.printStackTrace();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top