Java

Downloading from FTP servers in Java

Some months ago I needed a program which did the following:

– Connectsto an FTP host

– Check everything inside the remote folder

– Download all the files

– Delete all the files

– Wait a minute until the next connection

I found a very tiny program which did it ok but it has a problem, it’s always hanging and the information I had to receive was not properly updated, so I took the decision to make myself a program to do the same. The decision of using Java as the programming language was easy, but my Java skills were not as good as a year ago.

Luckily I found a great class called JvFTP (Yes! You have guessed: Java FTP) that works. After some tries this was the result:

import cz.dhl.io.*;
import cz.dhl.ftp.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FTPClass {
    public static final int    BUFFER_SIZE = 10240;
    
    public static void ftpdownload(String host, String user, String pass) {
        /*
         * Creates the connection to the FTP Server using the given parameters
         */
        FtpConnect cn = FtpConnect.newConnect(“ftp://” + host);
        cn.setUserName(user);
        cn.setPassWord(pass);
        Ftp cl = new Ftp();

        try {
            /*
             * Connects to the host
             */
            cl.connect(cn);

            /*
             * Gets current path
             */
            CoFile dir = new FtpFile(cl.pwd(), cl);

            /*
             * Gets the list of files inside the directory
             */
            CoFile fls[] = dir.listCoFiles();
            if (fls != null)
                for (int n = 0; n < fls.length; n++) {
                    /*
                     * Prints the name of the file. If it’s a directory it’ll be discarded
                     */
                    System.out.println(
                        fls[n].getName() + (fls[n].isDirectory() ? “/” : “”));
                    String pathFile = fls[n].getName() + (fls[n].isDirectory() ? “/” : “”);
                    /*
                     * Creates the InputStream from the FTP connection
                     */
                    FtpFile file = new FtpFile(pathFile, cl);              
                    InputStream in = file.getInputStream();
                    /*
                     * Creates the OutputStream to the file in the local disk
                     */
                    OutputStream out= new FileOutputStream(fls[n].getName());
                    byte[] buffer= new byte[BUFFER_SIZE];
                    /*
                     * Reads and writes…
                     */
                    while (true) {
                      int k= in.read(buffer);
                      if (k < 0)
                        break;
                      out.write(buffer, 0, k);
                    }
                    in.close();
                    out.close();
                }
            
        } catch (IOException e) {
            System.out.println(e);
        } finally { /* disconnect from server
              * this must be always run */
            cl.disconnect();
        }
    }
    public static void main(String args[]) {
        ftpdownload(“myhost”, “myuser”, “mypass”);
    }
}

¡Java y XML se entienden!

Hace un par de semanas tuve que ponerme de nuevo manos a la obra en algo que había tocado poco o prácticamente nada. El mayo de mis problemas es que llevaba casi dos años sin tocar el lenguaje Java y aunque PHP se le parece no deja de ser solamente eso, que se le parece… pero ni de lejos llega a ser completamente el mismo lenguaje.

La historia es la siguiente. Desde hace ya bastante tiempo veníamos usando un programita que nos hicieron en su día en VisualBasic, que para colmo de males no tenemos ni el código fuente, que cogía los teletipos que provenían de una agencia de noticias en formato XML y los traspasaba, previamente habiendo sido analizados, a una base de datos. El problema vino cuando dichos teletipos cambiaron internamente el formato. El programa no los reconocía. Ni corto ni perezoso abrí mi queridísimo Eclipse, instalé nuevamente el compilador de Java y ¡¡a trabajar!!

La primera decisión, ¿qué librería usaremos para leer los XMLs? En fin, tiré de biblioteca universitaria desempolvando mis viejos apuntes de carrera de cuando programar en Java era algo que tenía que hacer todos los días y… entonces recordé aquellos “maravillosos” momentos en los que SAXBuilder me tuvo un día hasta cerca de las 3:30 de la madrugada para poder hacer una práctica. Como se suele decir, más vale malo conocido que bueno por conocer, así que está claro que si en su día funcionó, ¿por qué no lo va a hacer otra vez?

Tras unas cuantas horas comiéndome el coco la verdad es que la historia quedó bastante elegante. Os dejo aquí un par de funciones que he implementado, ya que incorporar a esta entrada del blog el programa entero sería un absurdo y lo interesante es que se vea lo sencillo que es recorrer un XML en Java una vez que se conoce la estructura interna del mismo.

Comencemos con el programita…

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

Para leer un archivo XML dado se debe de hacer de la siguiente manera. Primeramente se crea un objeto de clase SAXBuilder que será donde cargaremos el XML. A continuación leemos el archivo desde el disco utilizando el objeto creado y pasándole como parámetro la ruta del archivo que deseamos analizar. Finalmente se crea un objeto de clase Element (¡sí! ¡Element! ¡Viva lo genérico!) y mediante el método getRootElement tendremos ya lista la raíz del archivo XML para empezar a trabajar.

SAXBuilder builder = new SAXBuilder();
Document doc=builder.build(“c:midirectorioarchivo.xml”);
Element e = doc.getRootElement();

¿Y ahora qué hacemos con todo esto?

Imaginemos que nuestro xml internamente tuviera algo así..

<raíz>

<identificador>12345</identificador>

….

</raíz>

… y quisiéramos leer lo que hay en identificador. Una forma un tanto “animal” sería la siguiente:

encontrado = false;

List<Element> elementos = e.getChildren();
Iterator i = elementos.iterator();
while ((i.hasNext()) && (!encontrado)) {
Element e2 = (Element) i.next();
String texto = e2.getName();
if (texto == “identificador”) {
String identificador = e2.getText();
encontrado = true;
}

y en nuestra variable identificador tendriamos el texto que hay en la etiqueta <identificador> del XML.

Otra forma un tanto más elegante de hacerlo, y que conste que el código se podría mejorar muchísimo más pero que conste que es un simple ejemplo, sería la siguiente…

public static Element getSubNodo(Element e, String subnodo) {
List<Element> elementos = e.getChildren();
Iterator i = elementos.iterator();
while (i.hasNext()) {
Element e2 = (Element) i.next();
String texto = e2.getName();
if (texto == subnodo)
return e2;
}
return e;
}

public static String buscarIdentificador(Element e) {
        String devuelve = “”;
        Element nodo = getSubNodo(e, “identificador”);
        devuelve = nodo.getText();
        return devuelve;
    }

Y la llamada sería:

String identificador = buscarIdentificador(e);

Pues con estas dos bonitas funciones y un par más de mi cosecha que buscaban aún más “hondamente” dentro del XML se pudo leer sin problemas el XML en cuestión, quitando de un plumazo un programa hecho en el horrible, vetusto y anticuado VisualBasic por algo más decente y moderno como es una aplicación hecha en Java.