2012-08-16 17 views
6

Per qualche motivo questo codice risulta in un file text.txt troncato. Dovrebbe (secondo me) scrivere 1000 risultati, ma il file di output ha varie quantità di righe (a seconda della corsa). Stranamente, la scrittura sul file si interrompe nel mezzo del comando di scrittura, in modo tale che una riga potrebbe non essere completa. Attualmente, le ultime tre righe del file di testo per l'ultima esecuzione erano le seguenti:bufferedwriter si arresta nel mezzo della scrittura

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

e il gioco è fatto. Nient'altro dopo.

Ecco il codice:

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

Penso che dovresti assicurarti che 'close()' venga chiamato sull'oggetto 'out'. –

risposta

16

Hai dimenticato di chiudere() lo scrittore, quindi non hai mai dato la possibilità di svuotare l'output bufferizzato su disco.

+0

Eccolo! Grazie mille! – user1602004

2

Si dovrebbe considerare il flusso di risciacquo dopo ogni scrittura. Prova qualcosa del genere:

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

Inoltre, è necessario assicurarsi di chiudere il flusso al termine dell'operazione. Un buon modo per strutturare il programma potrebbe essere questo:

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

Perché lavare dopo ogni iterazione? Non è inefficiente? Probabilmente, la dimensione del buffer potrebbe essere impostata in modo esplicito per consentire allo scrittore di decidere quando eseguire il flush, se la dimensione del buffer predefinita non è quella desiderata. – Vikdor

+0

@Vikdor - Concordo. Era inefficiente. Aggiornato la mia risposta! Grazie per averlo indicato :) – Sujay

+2

Chiamare 'flush()' immediatamente prima di 'close()' sui writer standard e OutputStreams nel pacchetto java.io è ridondante. Tutti si accertano che scarichino il loro output quando chiamate 'close()'. –

2

Due cose.

  1. Flush il flusso
  2. Chiudere il flusso

provare qualcosa di simile:

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

cercare di ricordare, si tratta di un "buffer". Ciò significa che mantiene le cose archiviate in memoria fino a quando non decide che deve essere scritto o se gli chiedi esplicitamente di "svuotare" il contenuto.

Inoltre, si dovrebbe sempre close i tuoi flussi. Ciò impedisce possibili problemi di file bloccati e problemi di gestione file: P

+1

Non c'è bisogno di 'flush()' lo stream a meno che qualcos'altro voglia iniziare a leggerlo prima che tu abbia finito di scriverlo o c'è una possibilità che 'close()' non sarà mai chiamato. –

+0

@AdrianPronk Sono solo paranoico: D – MadProgrammer

Problemi correlati