【问题标题】:bufferedwriter stops in the middle of writingbufferedwriter 在写入过程中停止
【发布时间】:2012-08-16 01:38:38
【问题描述】:

由于某种原因,此代码会导致 text.txt 文件被截断。它应该(根据我)写出 1000 个结果,但输出文件有不同数量的行(取决于运行)。奇怪的是,对文件的写入在写入命令的中间停止,因此一行可能不完整。目前,最新运行的文本文件的最后三行如下:

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

就是这样。之后就没有别的了。

代码如下:

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

}

【问题讨论】:

  • 我认为您应该确保在 out 对象上调用 close()

标签: java text-files bufferedwriter


【解决方案1】:

您忘记 close() 写入器,因此您从未给它机会将缓冲的输出刷新到磁盘。

【讨论】:

    【解决方案2】:

    两件事。

    1. 刷新流
    2. 关闭信息流

    尝试类似:

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

    请记住,它是一个“缓冲区”。这意味着它将内容存储在内存中,直到它决定需要写入或明确要求它“刷新”它的内容。

    此外,您应该始终close 您的信息流。这可以防止可能的锁定文件问题和文件句柄问题:P

    【讨论】:

    • 没有必要 flush() 流,除非在你写完之前有其他东西想开始读取它,或者有可能永远不会调用 close()
    • @AdrianPronk 我只是偏执:D
    【解决方案3】:

    您应该考虑在每次写入后刷新您的流。试试这样的:

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

    您还应确保在操作结束时关闭您的信息流。构建程序的一个好方法可能是:

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

    【讨论】:

    • 为什么每次迭代后都要刷新?这不是低效吗?如果默认缓冲区大小不是所需的大小,可能可以显式设置缓冲区大小以让写入者决定何时刷新。
    • @Vikdor - 我同意。这是低效的。更新了我的答案!感谢您指出这一点:)
    • 在 java.io 包中的标准 Writers 和 OutputStreams 上紧接在 close() 之前调用 flush() 是多余的。当您调用 close() 时,它们都会确保刷新输出。
    【解决方案4】:

    一旦您打开 io(Reader、Writter 或 BufferR/W,...),您必须稍后关闭它以关闭该流并释放资源。 如果您的代码有嵌套流 (File, FileReader, BufferedReader) 或 (Writer1, Writer2), 在使用 Writer2 之前,您必须在 (BufferedReader, FileReader, File) 或 (Writer1.close() 之后单独关闭它)

    【讨论】:

      猜你喜欢
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多