txt sobreescribir modificar manejo leer guardar ejemplos datos como archivos archivo java file-io bufferedwriter

sobreescribir - modificar archivos txt en java



BufferedWriter no escribe todo en su archivo de salida (8)

Tengo un programa Java que lee un texto de un archivo, línea por línea, y escribe texto nuevo en un archivo de salida. Pero no todo el texto que escribo en mi BufferedWriter aparece en el archivo de salida una vez que el programa ha finalizado. ¿Porqué es eso?

Los detalles: el programa toma un documento de texto CSV y lo convierte en comandos SQL para insertar los datos en una tabla. El archivo de texto tiene más de 10000 líneas que se parecen a las siguientes:

2007,10,9,1,1,1006134,19423882

El programa parece funcionar bien, excepto que simplemente se detiene en el archivo aleatoriamente a mitad de camino creando una nueva instrucción SQL que lo ha impreso en el archivo SQL. Se ve algo así como:

insert into nyccrash values (2007, 1, 2, 1, 4, 1033092, 259916); insert into nyccrash values (2007, 1, 1, 1, 1, 1020246, 197687); insert into nyccrash values (2007, 10, 9, 1

Esto ocurre después de aproximadamente 10000 líneas pero varios cientos de líneas antes del final del archivo. Donde la ruptura ocurre es entre 1 y a,. Sin embargo, los caracteres no parecen importantes porque si cambio el 1 a un 42 lo último que se escribe en el nuevo archivo es 4 , que está cortando el 2 de ese número entero. Entonces parece que el lector o escritor debe estar muriendo después de escribir / leer una cierta cantidad.

Mi código de Java es el siguiente:

import java.io.*; public class InsertCrashData { public static void main (String args[]) { try { //Open the input file. FileReader istream = new FileReader("nyccrash.txt"); BufferedReader in = new BufferedReader(istream); //Open the output file. FileWriter ostream = new FileWriter("nyccrash.sql"); BufferedWriter out = new BufferedWriter(ostream); String line, sqlstr; sqlstr = "CREATE TABLE nyccrash (crash_year integer, accident_type integer, collision_type integer, weather_condition integer, light_condition integer, x_coordinate integer, y_coordinate integer);/n/n"; out.write(sqlstr); while((line = in.readLine())!= null) { String[] esa = line.split(","); sqlstr = "insert into nyccrash values ("+esa[0]+", "+esa[1]+", "+esa[2]+", "+esa[3]+", "+esa[4]+", "+esa[5]+", "+esa[6]+");/n"; out.write(sqlstr); } } catch(Exception e) { System.out.println(e); } } }


Un recurso que debe cerrarse cuando ya no es necesario.

finally { out.close();//this would resolve the issue }

Algunas cosas a considerar:

  • BufferedWriter.close() vacía el búfer de la secuencia subyacente , por lo que si olvida flush() y no cierra, es posible que su archivo no tenga todo el texto que le escribió.
  • BufferedWriter.close() también cierra el Writer envuelto. Cuando se trata de un FileWriter, esto finalmente cerrará un FileOutputStream y le indicará al sistema operativo que ha terminado de escribir en el archivo.
  • El recolector de basura llamará automáticamente a close() , no en el BufferedWriter o en el FileWriter envuelto, sino en el FileOuputStream. Entonces, el sistema operativo estará contento, pero debe esperar el GC.
  • Sin embargo, siempre desea liberar los recursos del sistema operativo tan pronto como ya no los necesite. Esto se aplica a archivos abiertos, conexiones a bases de datos, colas de impresión ... cualquier cosa. Confía en mí esta vez.
  • BufferedWriter.close() borra el búfer de caracteres interno, de modo que la memoria estará disponible para la recolección de elementos no utilizados, incluso si el BufferedWriter permanece en el alcance.

Por lo tanto, siempre cierre sus recursos (no solo archivos) cuando haya terminado con ellos.

Si realmente quieres un vistazo bajo la tapa, la mayor parte de la fuente de la API de Java está disponible. BufferedWriter está here .


Como está utilizando BufferedWriter, también puede descargar el búfer cuando corresponda:

out.flush()

Esto escribirá el resto del búfer en el archivo real. El método Close también vacía el búfer y cierra el archivo.

out.close()

Puede haber situaciones en las que desee eliminar el búfer sin cerrar el archivo. En estas situaciones, puede usar el método de lavado.

También puede usar el método newline de BuffredWriter en lugar de agregar / n al final de la línea. El método Newline utiliza un separador de línea específico del sistema para que su código funcione en diferentes plataformas.

out.newLine()


Debes close() tu BufferedWriter . Debe close() su BufferedWriter porque es un Writer y, por lo tanto, implementa AutoCloseable , lo que significa (énfasis añadido) es

Un recurso que debe cerrarse cuando ya no es necesario.

Algunas personas dicen que primero debes llamar a flush() para tu BufferedWriter antes de llamar a close() . Están equivocados. La documentación de BufferedWriter.close() indica que "Cierra la secuencia y la vacía primero " (énfasis añadido).

La semántica documentada de la descarga ( flush() ) son

Vacía esta secuencia al escribir cualquier salida almacenada en el flujo subyacente

Por lo tanto, debe close , y close va a enjuagar cualquier salida con búfer.

Su archivo de salida no incluye todo el texto que escribió en su BufferedWriter porque almacenó parte de ese texto en un búfer. El BufferedWriter nunca vació ese búfer y lo pasó al archivo porque nunca se lo pidió.

Desde Java 7, la mejor manera de garantizar que un recurso de AutoCloseable , como BufferedWriter , se cierre cuando ya no es necesario utilizar la gestión automática de recursos (ARM), también conocida como try-with-resources :

try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) { // writes to out here } catch (IOException ex) { // handle ex }

También debe close su BufferedReader cuando ya no lo necesite, por lo que debe haber anidado los bloques try-with-resources:

try (BufferedReader in = new BufferedReader(new FileReader("nyccrash.txt")) { try (BufferedWriter out = new BufferedWriter(new FileWriter("nyccrash.sql"))) { // your reading and writing code here } } catch (IOException ex) { // handle ex }


Siempre cierre sus recursos (no solo archivos) cuando haya terminado con ellos.

finally { out.close();//this would resolve the issue }

Puede haber situaciones en las que desee eliminar el búfer sin cerrar el archivo. En estas situaciones, puede usar el método de lavado.


Su código no parece estar cerrando el escritor después de que haya terminado de escribir en él. Agregue un out.close() (preferiblemente en un bloque finally) y debería funcionar correctamente.


no cierre su BufferedWriter.close dentro de un bloque finally

finally { out.close();//this would resolve the issue }


no cierre su BufferedWriter.close dentro de un bloque finally

finally { out.close();//this would resolve the issue }

Esto funciona. Me he enfrentado al mismo problema y esto funcionó para mí ... Buena suerte :)


OutputStream cerrar su OutputStream que OutputStream el resto de sus datos:

out.close();

El tamaño de búfer predeterminado para BufferedWriter es 8192 caracteres , lo suficientemente grande como para contener fácilmente cientos de líneas de datos no escritos.