2012-08-16 13 views
6

Por alguna razón, este código da como resultado un archivo text.txt truncado. Debería (según yo) escribir 1000 resultados, pero el archivo de salida tiene varias cantidades de líneas (dependiendo de la ejecución). Extrañamente, la escritura en el archivo se detiene en el medio del comando de escritura, de modo que una línea puede no estar completa. Actualmente, las últimas tres líneas del archivo de texto para la última ejecución fueron las siguientes:bufferferedwriter se detiene en el medio de la escritura

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

y eso es todo. Nada más después de eso.

Aquí está el código:

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

Creo que debes asegurarte de que se llama a 'close()' en el objeto 'out'. –

Respuesta

16

Se olvidó de cerrar() el escritor, por lo que nunca le dio la oportunidad de enjuagar la salida almacenada en el disco.

+0

¡Allí está! ¡Muchas gracias! – user1602004

2

Debe tener en cuenta el lavado de su corriente después de cada escritura. Pruebe algo como esto:

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

También debe asegurarse de cerrar la secuencia al final de su operación. Una buena forma de estructurar su programa podría ser esta:

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

¿Por qué enjuagar después de cada iteración? ¿No es eso ineficiente? Probablemente, el tamaño del búfer se podría establecer explícitamente para permitirle al escritor decidir cuándo vaciar, si el tamaño del búfer predeterminado no es el deseado. – Vikdor

+0

@Vikdor - Estoy de acuerdo. Fue ineficiente. Actualizado mi respuesta! Gracias por señalarlo :) – Sujay

+2

Llamar 'flush()' inmediatamente antes de 'close()' en los Writers y OutputStreams estándar en el paquete java.io es redundante. Todos ellos aseguran que descargan su salida cuando llamas 'close()'. –

2

Dos cosas.

  1. Enjuague la corriente
  2. cerrar la secuencia

intentar algo como:

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

tratar de recordar, se trata de un "buffer". Eso significa que mantiene las cosas almacenadas en la memoria hasta que decida que debe escribirse o explícitamente le pides que "descargue" sus contenidos.

Además, siempre debe close las transmisiones. Esto evita posibles problemas de archivos bloqueados y problemas con el manejo de archivos: P

+1

No hay necesidad de 'vaciar()' la transmisión a menos que otra cosa quiera comenzar a leerla antes de que haya terminado de escribirla o existe la posibilidad de que 'close()' nunca se invoque. –

+0

@AdrianPronk Estoy paranoico: D – MadProgrammer

Cuestiones relacionadas