FULL PRODUCT VERSION :
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)
FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
If a BufferedWriter is used to write to a file, and an IOException occurs during the flush call in BufferedWriter.close(), then the file will not be closed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a floppy disk with little (e.g., 1K) free disk space.
Run the attached program.
When prompted, specify the name for a new file on the floppy disk.
The program should display the message "Closing the writer." on standard error, then display a dialog instructing you to try to delete the file.
Try to delete the file.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
You should be able to delete the file, BufferedWriter.close() was called.
ACTUAL -
You cannot delete the file.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.*;
import javax.swing.*;
/**
* This program illustrates that some writers, such as BufferedWriter and
* OutputStreamWriter, don't close the underlying Writer or OutputStream if an
* exception is thrown during the close operation.
*
* The works by determining the number of strings that need to be written to
* a file on a given directory in order for a flush operation to throw an
* IOException. It then uses the standard approach of wrapping a FileWriter in
* a BufferedWriter to write the file. After writing the file, the BufferedWriter
* is closed. The program then displays a dialog that asks to user to verify
* that the file is still open by trying to delete the file.
*
* The program determines the number of strings that need to be written by
* writing strings to a temporary file in the target directory. Once it has
* written enough strings to cause an IOException, it closes and deletes the
* file. The approach used to create this file is to wrap a FileOutputStream
* in an OutputStreamWriter and BufferedWriter. Closing the FileOutputStream
* actually closes the underlying file, which allows it to be deleted. This
* approach provides a workaround for the defect.
*/
public class CloseFailure
{
public static void main (String[] args)
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle ("Specify a file on a floppy disk with little free space.");
if (chooser.showSaveDialog (null) != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
int nWrites = determineWritesRequired (file.getParentFile());
Writer writer = null;
try
{
writer = new BufferedWriter (new FileWriter (file));
writeNStrings (writer, nWrites);
System.err.println ("Closing the writer.");
writer.close();
} catch (IOException ioe) {
JOptionPane.showMessageDialog (null,
"You can verify that the file is still open\nby trying to delete it.");
} finally {
System.exit (0);
} // try
} // main
private static final String SOME_STRING =
"This program illustrates a defect in the implementation of BufferedWriter.close().\n";
/**
* Return the number of SOME_STRINGs that need to be written to the
* given directory to cause an IOException when the writer is flushed.
*/
private static int determineWritesRequired (File directory)
{
File file = null;
OutputStream stream = null;
Writer writer = null;
int result = 0;
try
{
file = File.createTempFile ("Temp", ".txt", directory);
stream = new FileOutputStream (file);
writer = new BufferedWriter (new OutputStreamWriter (stream));
while (true)
{
++result;
writer.write (SOME_STRING);
writer.flush();
} // while
} catch (IOException ioe) {
try
{
stream.close();
file.delete();
} catch (IOException e) {
e.printStackTrace();
} // try
} // try
return result;
} // determineWritesRequired
/**
* Write n SOME_STRINGS to the given Writer.
*/
private static void writeNStrings (Writer writer, int n) throws IOException
{
try
{
for (int i = 0; i < n; ++i)
writer.write (SOME_STRING);
} catch (IOException e) {
System.err.println ("We didn't get the number of writes correct.");
} // try
} // writeSomeStuff
} // CloseFailure
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Wrap a FileOutputStream in an OutputStreamWriter instead of using a FileWriter and close the FileOutputStream if there is an exception writing to or closing the Writer.
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)
FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
If a BufferedWriter is used to write to a file, and an IOException occurs during the flush call in BufferedWriter.close(), then the file will not be closed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a floppy disk with little (e.g., 1K) free disk space.
Run the attached program.
When prompted, specify the name for a new file on the floppy disk.
The program should display the message "Closing the writer." on standard error, then display a dialog instructing you to try to delete the file.
Try to delete the file.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
You should be able to delete the file, BufferedWriter.close() was called.
ACTUAL -
You cannot delete the file.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.*;
import javax.swing.*;
/**
* This program illustrates that some writers, such as BufferedWriter and
* OutputStreamWriter, don't close the underlying Writer or OutputStream if an
* exception is thrown during the close operation.
*
* The works by determining the number of strings that need to be written to
* a file on a given directory in order for a flush operation to throw an
* IOException. It then uses the standard approach of wrapping a FileWriter in
* a BufferedWriter to write the file. After writing the file, the BufferedWriter
* is closed. The program then displays a dialog that asks to user to verify
* that the file is still open by trying to delete the file.
*
* The program determines the number of strings that need to be written by
* writing strings to a temporary file in the target directory. Once it has
* written enough strings to cause an IOException, it closes and deletes the
* file. The approach used to create this file is to wrap a FileOutputStream
* in an OutputStreamWriter and BufferedWriter. Closing the FileOutputStream
* actually closes the underlying file, which allows it to be deleted. This
* approach provides a workaround for the defect.
*/
public class CloseFailure
{
public static void main (String[] args)
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle ("Specify a file on a floppy disk with little free space.");
if (chooser.showSaveDialog (null) != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
int nWrites = determineWritesRequired (file.getParentFile());
Writer writer = null;
try
{
writer = new BufferedWriter (new FileWriter (file));
writeNStrings (writer, nWrites);
System.err.println ("Closing the writer.");
writer.close();
} catch (IOException ioe) {
JOptionPane.showMessageDialog (null,
"You can verify that the file is still open\nby trying to delete it.");
} finally {
System.exit (0);
} // try
} // main
private static final String SOME_STRING =
"This program illustrates a defect in the implementation of BufferedWriter.close().\n";
/**
* Return the number of SOME_STRINGs that need to be written to the
* given directory to cause an IOException when the writer is flushed.
*/
private static int determineWritesRequired (File directory)
{
File file = null;
OutputStream stream = null;
Writer writer = null;
int result = 0;
try
{
file = File.createTempFile ("Temp", ".txt", directory);
stream = new FileOutputStream (file);
writer = new BufferedWriter (new OutputStreamWriter (stream));
while (true)
{
++result;
writer.write (SOME_STRING);
writer.flush();
} // while
} catch (IOException ioe) {
try
{
stream.close();
file.delete();
} catch (IOException e) {
e.printStackTrace();
} // try
} // try
return result;
} // determineWritesRequired
/**
* Write n SOME_STRINGS to the given Writer.
*/
private static void writeNStrings (Writer writer, int n) throws IOException
{
try
{
for (int i = 0; i < n; ++i)
writer.write (SOME_STRING);
} catch (IOException e) {
System.err.println ("We didn't get the number of writes correct.");
} // try
} // writeSomeStuff
} // CloseFailure
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Wrap a FileOutputStream in an OutputStreamWriter instead of using a FileWriter and close the FileOutputStream if there is an exception writing to or closing the Writer.
- duplicates
-
JDK-6266377 BufferedWriter.close() fails to release resources if exception occurs during flush
-
- Resolved
-