2009-05-25 29 views
34

En un programa Java (Java 1.5), tengo un BufferedWriter que envuelve un FileWriter, y que llamo escritura() muchas veces ... El archivo resultante es bastante grande ...para eliminar un BufferedWriter

Entre las líneas de este archivo, algunas están incompletas ...

¿Debo llamar a flush cada vez que escribo algo (pero sospecho que sería ineficaz) o usar otro método de BufferedWriter o usar otra clase? ...?

(Como tengo un montón de líneas por escribir, quiero tener algo bastante eficiente.) ¿Cuál sería el momento ideal de "enjuague"? (Cuando llegue a la capacidad de la BufferedWriter) ...

Init:

try { 
    analysisOutput = new BufferedWriter(new FileWriter(
     "analysisResults", true)); 
    analysisOutput.newLine(); 
    analysisOutput.write("Processing File " + fileName + "\n"); 
} 
catch (FileNotFoundException ex) { 
    ex.printStackTrace(); 
} 
catch (IOException ex) { 
    ex.printStackTrace(); 
} 

Escritura:

private void printAfterInfo(String toBeMoved,HashMap<String, Boolean> afterMap, Location location) 
    throws IOException { 
    if(afterMap != null) { 
     for (Map.Entry<String, Boolean> map : afterMap.entrySet()) { 
     if (toBeMoved == "Condition") { 
      if (1 <= DEBUG) 
      System.out.println("###" + toBeMoved + " " + location + " " 
       + conditionalDefs.get(conditionalDefs.size() - 1) 
       + " After " + map.getKey() + " " 
       + map.getValue() + "\n"); 

      analysisOutput.write("###" + toBeMoved + " " + location + " " 
       + conditionalDefs.get(conditionalDefs.size() - 1) 
       + " After " + map.getKey() + " " + map.getValue() 
       + "\n"); 
     } else { 
      if (1 <= DEBUG) 
      System.out.println("###" + toBeMoved + " " + location + " " 
       + map.getKey() + " After " 
       + map.getValue() + "\n"); 
      if (conditionalDefs.size() > 0) 
      analysisOutput.write("###" + toBeMoved + " " + location + " " 
       + conditionalDefs.get(conditionalDefs.size() - 1) + " " 
       + map.getKey() + " After " + map.getValue() 
       + "\n"); 
      else 
      analysisOutput.write("###" + toBeMoved + " " + location + " " + map.getKey() + " After " + map.getValue() + "\n"); 


     } 
     } 
    } 

acabo cuenta de que las líneas que sean incompletas son los que acaban de antes de "Procesar archivo" ... así ocurre cuando estoy cambiando de un archivo que analizo a otro ...

Cierre:

dispatch(unit); 

try { 
    if (analysisOutput != null) { 
    printFileInfo(); 
    analysisOutput.close(); 
    } 
} 
catch (IOException ex) { 
    ex.printStackTrace(); 
} 

veces la información impresa por printFileInfo no aparece en el archivo de resultados ...

+0

Si están incompletos, ¿tiene múltiples hilos escribiendo en él? IIRC a BufferedWriter NO es seguro para subprocesos, por lo que podría ser una explicación, pero NO tiene que "enjuagarse manualmente" para hacer más espacio, se encarga de eso. –

+0

Si no está seguro de que su pregunta sea clara, quizás proporcione una muestra de código o una muestra de salida que aclare. –

+0

En realidad es seguro para subprocesos (aunque los decoradores de Writer tienen problemas para acordar qué objeto bloquear). –

Respuesta

74

El BufferedWriter ya se vaciará cuando llene su memoria intermedia. A partir de los documentos de BufferedWriter.write:

Normalmente esto método almacena caracteres de la matriz dada en el búfer de esta corriente, vaciar el búfer a la corriente subyacente, según sea necesario.

(El subrayado es mío.)

El punto de BufferedWriter es, básicamente, para consolidar un montón de pequeñas escrituras en un número mucho menor grandes escrituras, ya que es generalmente más eficiente (pero más de un dolor para codificar). Sin embargo, no debería necesitar hacer nada especial para que funcione correctamente, salvo que se asegure de vaciarlo cuando esté terminado con, y llamar al close() hará esto y enjuagar/cerrar el escritor subyacente de todos modos.

En otras palabras, relájate, solo escribe, escribe, escribe y cierra :) La única vez que normalmente necesitas llamar al flush manualmente es si realmente, realmente necesitas que los datos estén en el disco ahora. (Por ejemplo, si tiene un registrador perpetuo, es posible que desee enjuagarlo de vez en cuando para que quien lea los registros no tenga que esperar hasta que el búfer esté lleno para poder ver nuevas entradas de registro)

+0

probado y aprobado. Se escribieron 10Mb de números línea por línea: lavado después de escribir cada línea - tarda 7 segundos, sin enjuagar - 4 segundos. –

8

En el momento en el lavado ideal es cuando se necesita otro programa que lee el archivo para ver los datos que se ha escrito, antes del archivo está cerrado. En muchos casos, eso nunca es.

+0

incluso si BufferedWriter es grande ... ¿No tengo que hacerlo en una etapa intermedia? – LB40

+0

Si el buffer se llena, escribirá su contenido en el disco. La API BufferedWriter está diseñada para ser un reemplazo directo para un FileWriter, con la excepción de consumir datos antes de que se cierre el archivo. – Dave

Cuestiones relacionadas