Archivo

Entradas Etiquetadas ‘file’

¿Como saber el tipo de un archivo? (I)

Sábado, 26 de febrero de 2011

Por alguna razón, este articulo viejo ha tenido algo de tráfico en los últimos días. Me dí cuenta que la idea de usar Java y JNI nunca se materializó, sólo dí unas pistas.

Una forma de hacer esto es llamando a la librería ‘magic’. Magic viene prácticamente en cualquier sistema operativo que se parezca a UNIX que se respete, como BSD, OSX y por supuesto Linux.

Si usted llama a la página man (man 3 libmagic) allí encontrará suficiente información. Por ejemplo, aquí les muestro un pequeño programa que hice en C el cual detecta el tipo de archivo que usted le pase por la línea de comandos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include 
#include 
 
/*
 * Program that shows how to use the magic library to figure out the type of a file
 * @author Jose V Nunez (josevnz@kodegeek.com)
 * License: BSD
 */
int main(int argc, char ** argv) {
 
        if (argc == 1) {
                printf("[ERROR]: Please provide the file name to check and try again!\n");
                return 1;
        }
 
        // See manpage libmagic for details on what this flags mean
        int flags = MAGIC_SYMLINK|MAGIC_COMPRESS|MAGIC_CONTINUE|MAGIC_PRESERVE_ATIME|MAGIC_ERROR;
 
        magic_t cookie = magic_open(flags);
        if (cookie == NULL) {
                printf("There was a problem opening the magic library!\n");
                return 1;
        }
        int status = magic_load(cookie, NULL);
        if (status != 0) {
                printf("Unable to load magic default database!, %s\n", magic_error(cookie));
                magic_close(cookie);
                return 1;
        }
 
        const char * file_details =  magic_file(cookie, argv[1]);
        printf("Type for file: %s is %s\n", argv[1], file_details);
 
        magic_close(cookie);
        return 0;
}

Para compilarlo les dejo un archivo Makefile:

1
2
3
CPPFLAGS += -O2 -L/Users/Shared/lib -I/Users/Shared/include -lmagic
all: magic.c
        $(CC) $(CPPFLAGS) magic.c -o magic

Y finalmente como se corre:

1
2
3
4
5
auyan:c josevnz$ make
cc -O2 -L/Users/Shared/lib -I/Users/Shared/include -lmagic magic.c -o magic
auyan:c josevnz$ ./magic /Users/josevnz/CTX.DAT
Mime type for file: /Users/josevnz/CTX.DAT is Java serialization data, version 5
auyan:c josevnz$

En la siguiente entrada las prometo como hacer esto desde Java (pista, vamos a utilizar JNI).

–José

c, java, mime magic libmagic jni java, opensource, programación , , , , , ,

Echando código: ¿Como saber de que tipo es un archivo, desde JAVA?

Sábado, 22 de septiembre de 2007

Nock Nock Neo
Con JNI nos podemos ir a bajo nivel con el sistema operativo. Una rubia en la foto :)

En un articulo anterior les habia comentado como trabajar con JNI y Java. En esta ocasión escogí un problema un poco más complicado, ya que el anterior parecía más un “Hola Mundo” que otra cosa (si, pasos de bebé).

Así que como la necesidad es la madre de todas las invenciones, me decidí a probar un ejemplo que tenia ganas de poner en práctica desde hace tiempo. En este caso se trata de como obtener el tipo de un archivo utilizando la herramienta file en UNIX, pero primero veamos si Java puede hacer lo mismo.

En Java podemos utilizar Swing para obtener el tipo del archivo. Leí que clase JFileChooser de Swing te da información similar, pero es basado en la extensión del archivo:

–>

   1:import javax.swing.JFileChooser;
   2:import java.io.File;
   3:
   4:public class FileType {
   5:        public static void main(String [] args) throws Exception {
   6:                JFileChooser view = new JFileChooser();
   7:                String descr = view.getTypeDescription(new File(args[0]));
   8:                System.out.println("File type is: " + descr);
   9:        }
  10:}

Corriendo el programita:

[josevnz@localhost ~]$ javac FileType.java -d .
[josevnz@localhost ~]$ java FileType DS156_Complete.pdf
File type is: Generic File
[josevnz@localhost ~]$


Poco satisfactorio, por no decir otra cosa. Sin embargo todo el mundo sabe como obtener el tipo de un archivo desde unix, utilizando ‘file’:

[josevnz@localhost ~]$ file DS156_Complete.pdf
DS156_Complete.pdf: PDF document, version 1.3
[josevnz@localhost ~]$

File es una de mis herramientas favoritas. File consulta una base de datos en la cual están registrados los formatos y utilizando reglas heuristicas determina el verdadero tipo del archivo. Ahora, supongamos que quiero tener la misma funcionalidad desde uno de mis programas en Java, ¿como hacer?

Lo primero es averiguar como los verdaderos expertos lo hacen. Hay que utilizar JNI ya que quiero tomar ventaja de que el código de file va a utilizar la base de datos que viene con cada sistema operativo UNIX y no me importa sacrificar portabilidad.

Así que después buscar cuidadosamente en Google, finalmente encontré la página oficial del comando ‘file’.

Sin embargo ya alguién se topó con el problema y decidió hacer una interfaz en Java la cual hace todo el trabajo: Java shared mime info.

Así que esas son las opciones. Les dejo la de Java, aunque otros lenguajes ya tienen sus respectivas implementaciones.

Blogalaxia.com:file, java, linux, open source, venezuela, libmagic, jmimeinfo
Technorati.com:file, java, linux, open source, venezuela, libmagic, jmimeinfo

java , , , , , ,