Failed to display data list in Java

2

In the following method:

generateFile (String filename, String country)

Generate a text file that contains the list of offices in the last country as the second parameter. The file must have the last name as the first parameter. The field separator must be the semicolon (;), the record separator the line break. All fields in the Offices table should be saved.

It correctly generates the file nombreArchivo.txt as we see below in the main, only that it does not write the list of the country offices that I indicated in the second parameter, in this case, for example, " USES". Printing on the screen does it correctly (my capture); but I want you to generate the same listing in .txt and do not do it. What could be the reason?

Method of the class that shows it on the screen well:

public static void generarArchivo(String nombreArchivo, String pais) throws SQLException, ClassNotFoundException, FileNotFoundException {
        ConectarSingleton conexion=new ConectarSingleton();
        Connection con = conexion.getConexion();

        ResultSet rs = GestionClassic.consultar("select * from oficinas where pais ='"+pais+"'");
        while(rs.next()) {
            System.out.println(rs.getString(1)+";"+rs.getString(2)+";"+rs.getString(3)+";"+rs.getString(4)+";"
            +rs.getString(5)+";"+rs.getString(6)+";"+rs.getString(7)+";"+rs.getString(8)+";"+rs.getString(9));

        }
    }

Method of the class that does not write data to the file:

public static void generarArchivo(String nombreArchivo, String pais) throws SQLException, ClassNotFoundException, FileNotFoundException {
        ConectarSingleton conexion=new ConectarSingleton();
        Connection con = conexion.getConexion();
        PrintWriter pw = new PrintWriter(nombreArchivo);

        ResultSet rs = GestionClassic.consultar("select * from oficinas where pais ='"+pais+"'");
        while(rs.next()) {
            pw.println(rs.getString(1)+";"+rs.getString(2)+";"+rs.getString(3)+";"+rs.getString(4)+";"
            +rs.getString(5)+";"+rs.getString(6)+";"+rs.getString(7)+";"+rs.getString(8)+";"+rs.getString(9));

        }
    }

main:

public static void main(String[] args) {

 try {  

GestionClassic.generarArchivo("nombreArchivo.txt", "USA");

        } catch (SQLException  | ClassNotFoundException | FileNotFoundException ex) {
            System.out.println(ex.getMessage());
        } 
    }
    
asked by user09b 09.08.2018 в 22:41
source

1 answer

2

Data lost in the file

The problem you're suffering is because PrintWriter , as well as PrintStream , does not automatically dump the contents of the buffer into the data stream if it is not activated in some of the constructor methods, so that data could be left unsent (in this case case, without writing to the file).

Let's take the following example:

import java.io.PrintWriter;
public class Prueba {
  public static void main(String[] args) {
    try {
      PrintWriter pw = new PrintWriter("prueba.txt");
      pw.println("hola");
    } catch (Exception e) { }
  }
}

When executed, the file would be empty.

To solve it you have three possibilities:

  • Force the writing by using flush() or close() .
  • Enable automatic data dump after print() or println() using a constructor that allows it.

Force explicit writing with flush()

import java.io.PrintWriter;
public class Prueba {
  public static void main(String[] args) {
    try {
      PrintWriter pw = new PrintWriter("prueba.txt");
      pw.println("hola");
      pw.flush();
    } catch (Exception e) { }
  }
}

Close the file with close()

import java.io.PrintWriter;
public class Prueba {
  public static void main(String[] args) {
    try {
      PrintWriter pw = new PrintWriter("prueba.txt");
      pw.println("hola");
      pw.close();
    } catch (Exception e) { }
  }
}

Automatic dump with the constructor OutputStream

import java.io.PrintWriter;
import java.io.FileOutputStream;
public class Prueba {
  public static void main(String[] args) {
    try {
      PrintWriter pw = new PrintWriter(new FileOutputStream("prueba.txt"), true);
      pw.println("hola");
      pw.close();
    } catch (Exception e) { }
  }
}

Prepared consultations

You should not concatenate strings to an SQL query. You could have problems if the variable contains single quotes (for example, that the parameter pais is worth Salem's Lot ).

To fix it you should use JDBC prepared queries overloading in the following way the method consultar() of your previous question :

public static ResultSet consultar(
  String sql,
  String parametro1
) throws SQLException, ClassNotFoundException {
  ConectarSingleton conexion = new ConectarSingleton();
  Connection con = ConectarSingleton.getConexion(); 
  /* Preparamos la consulta */
  PreparedStatement sentencia = con.prepareStatement(sql);
  /* Asignamos al primer ? el valor de parametro1 */
  sentencia.setString(1, parametro1);
  /* Ejecutamos la consulta como de costumbre */
  ResultSet resultados = sentencia.executeQuery();
  return resultados;
}  

public static void generarArchivo(
  String nombreArchivo,
  String pais
) throws SQLException, ClassNotFoundException, FileNotFoundException {
  ConectarSingleton conexion = new ConectarSingleton();
  Connection con = conexion.getConexion();
  PrintWriter pw = new PrintWriter(nombreArchivo);

  /* Llamamos al nuevo método indicando el primer parámetro: "pais" */
  ResultSet rs = GestionClassic.consultar(
    "SELECT * FROM oficinas WHERE pais = ?",
    pais
  );
  while(rs.next()) {
    pw.println(
      rs.getString(1) + ";"
      + rs.getString(2) + ";"
      + rs.getString(3) + ";"
      + rs.getString(4) + ";"
      + rs.getString(5) + ";"
      + rs.getString(6) + ";"
      + rs.getString(7) + ";"
      + rs.getString(8) + ";"
      + rs.getString(9)
    );
  }
}

This way, when you indicate a parameter that method will be executed that has an additional parameter of type String , assigning the first ? its value in a correct way without problems with single quotes ' and protecting your code against the Nefarious Effects of the SQL injection .

    
answered by 10.08.2018 / 09:05
source