bufferedwriter stops in the middle of writing

2019-02-22 01:28发布

问题:

For some reason this code results in a truncated text.txt file. It should (according to me) write out 1000 results, but the output file has various amounts of lines (depending on the run). Weirdly, the writing to the file stops in the middle of the write command, such that a line may not be complete. Currently, the last three lines of the text file for the latest run was as follows:

749, 78.97988, 97.80454, 99.6625, 94.00000015258789
750, 4.1745043, 86.64212, 107.59311, 71.00000008583069
751,

and that's it. Nothing else after that.

Here is the code:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Random;

public class ColorGrayScale {

/**
 * @param args
 * @throws IOException
 */
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    Writer out = new BufferedWriter(new FileWriter("test.txt"),16*1024);
    Random generator = new Random();
    float red = 0, green = 0, blue = 0;
    int i = 0;

    while (i<1000) {

        float grey = generator.nextInt(127) + 64;
        int sequence = generator.nextInt(6) + 1; // to pick from 1 of six
                                                    // orders
        switch (sequence) { // the various orders that red green and blue
                            // are going to be in
        case 1:
            red = (float) (generator.nextFloat() * (grey / .21));
            green = (float) (generator.nextFloat() * ((grey - (red * .21)) / .71));
            blue = (float) ((grey - (red * .21) - (green * .71)) / 0.08);
            break;
        case 2:
            red = (float) (generator.nextFloat() * (grey / .21));
            blue = (float) (generator.nextFloat() * ((grey - (red * .21)) / .08));
            green = (float) ((grey - (red * .21) - (blue * .08)) / 0.71);
            break;
        case 3:
            green = (float) (generator.nextFloat() * (grey / .71));
            red = (float) (generator.nextFloat() * ((grey - (green * .71)) / .21));
            blue = (float) ((grey - (red * .21) - (green * .71)) / .08);
            break;
        case 4:
            green = (float) (generator.nextFloat() * (grey / .71));
            blue = (float) (generator.nextFloat() * ((grey - (green * .71)) / .08));
            red = (float) ((grey - (green * .71) - (blue * .08)) / .21);
            break;
        case 5:
            blue = (float) (generator.nextFloat() * (grey / .08));
            red = (float) (generator.nextFloat() * ((grey - (blue * .08)) / .21));
            green = (float) ((grey - (blue * .08) - (red * .21)) / .71);
            break;
        case 6:
            blue = (float) (generator.nextFloat() * (grey / .08));
            green = (float) (generator.nextFloat() * ((grey - (blue * .08)) / .71));
            red = (float) ((grey - (blue * .08) - (green * .71)) / .21);
            break;
        }
        if (red < 256 && blue < 256 && green < 256) {
             out.write("" + i + ", " + red + ", " + green + ", " + blue
                    + ", " + (.21 * red + .71 * green + 0.08 * blue + "\n"));
            i++;
        }
    }
}

}

回答1:

You forgot to close() the writer, so you never gave it a chance to flush buffered output to disk.



回答2:

Two things.

  1. Flush the stream
  2. Close the stream

Try something like:

 Writer out = null;
 try {
    out = new BufferedWriter(new FileWriter("test.txt"),16*1024);

    // Write some stuff

    out.flush();
 } finally {
    try {
        out.close();
    } catch (Exception exp) {
    }
}

Try and remember, it's a "buffer". That means that it's keeping stuff stored in memory until it decides it needs to be written or your explicitly ask it to "flush" it's contents.

Also, you should always close your streams. This prevents possible locked file issues and file handle issues :P



回答3:

You should consider flushing your stream after each write. Try something like this:

try{
    //your code
    out.write("" + i + ", " + red + ", " + green + ", " + blue
            + ", " + (.21 * red + .71 * green + 0.08 * blue + "\n"));
    i++;
}finally{
    //Close the stream
    out.close();
}

Also you should make sure that you close your stream at the end of your operation. A good way to structure your program might be this:

Random generator = new Random();
float red = 0, green = 0, blue = 0;
int i = 0;

Writer out = null;

try{
    out = new BufferedWriter(new FileWriter("test.txt"), 16 * 1024);

    while (i < 1000) {
        //your logic
        if (red < 256 && blue < 256 && green < 256) {
                out.write("" + i + ", " + red + ", " + green + ", " + blue
                        + ", " + (.21 * red + .71 * green + 0.08 * blue + "\n"));
                i++;
        }
    }
}finally{
    if(out != null){
        out.close();
    }
}


回答4:

Once you open io (Reader, Writter or BufferR/W, ...), you have to close it later to close that stream and release the resource. Incase your code has nested stream (File, FileReader, BufferedReader) or (Writer1, Writer2), you have to close it separately order right after(BufferedReader, FileReader, File) or (Writer1.close() before using Writer2)