2010-06-22 25 views
5

Escribí el siguiente método para ver si un archivo particular contiene solo caracteres de texto ASCII o caracteres de control además de eso. ¿Podría echar un vistazo a este código, sugerir mejoras y señalar descuidos?¿Cómo comprobar si el archivo es binario?

La lógica es la siguiente: "Si los primeros 500 bytes de un archivo contienen 5 o más caracteres de control - Informe como archivo binario"

gracias.

public boolean isAsciiText(String fileName) throws IOException { 

    InputStream in = new FileInputStream(fileName); 
    byte[] bytes = new byte[500]; 

    in.read(bytes, 0, bytes.length); 
    int x = 0; 
    short bin = 0; 

    for (byte thisByte : bytes) { 
     char it = (char) thisByte; 
     if (!Character.isWhitespace(it) && Character.isISOControl(it)) { 

      bin++; 
     } 
     if (bin >= 5) { 
      return false; 
     } 
     x++; 
    } 
    in.close(); 
    return true; 
} 

Respuesta

3

Como llama a esta clase "isASCIIText", usted sabe exactamente lo que está buscando. En otras palabras, no es "isTextInCurrentLocaleEncoding". Por lo tanto puede ser más preciso con:

if (thisByte < 32 || thisByte > 127) bin++; 

edición, mucho tiempo después — se señaló en un comentario que esta sencilla prueba podría ser disparado por un archivo de texto que se inició con una gran cantidad de nuevas líneas. Probablemente sería mejor utilizar una tabla de bytes "ok" e incluir caracteres imprimibles (incluido el retorno de carro, la nueva línea y la pestaña, y posiblemente el formulario de feed, aunque no creo que muchos documentos modernos los usen), y luego verificar la mesa.

+0

Es una tragedia que esta se marca como la respuesta correcta, cuando este algoritmo sería clasificar un archivo que contiene "esta \ r \ nis \ r \ Nonly \ r \ ntext" como binario. – Ingo

+1

@Ingo verdadero; sería mejor verificar alguna proporción de caracteres de control a no controles, y también verificar casos especiales como los caracteres de control comunes en el texto. Era tan joven cuando escribí esta respuesta :) – Pointy

3

x Parece que no hace nada.

¿Qué pasa si el archivo es de menos de 500 bytes?

Algunos archivos binarios tienen una situación en la que puede tener un encabezado para los primeros N bytes del archivo que contiene algunos datos que son útiles para una aplicación pero que a la biblioteca no le importa el binario. Podría fácilmente tener más de 500 bytes de ASCII en un preámbulo como este seguido de datos binarios en el siguiente gigabyte.

debe manejar excepción si el archivo no se puede abrir o leer, etc.

1

La primera cosa que noté - sin relación a su pregunta real, pero debe ser el cierre de su flujo de entrada en un bloque para asegurar finally siempre está hecho. Por lo general, esto solo maneja excepciones, pero en su caso ni siquiera cerrará las secuencias de archivos al devolver false.

Aparte de eso, ¿por qué la comparación con los caracteres de control ISO? No es un archivo "binario", es un "archivo que contiene 5 o más caracteres de control". Una mejor manera de abordar la situación, en mi opinión, sería invertir el cheque: escriba una función isAsciiText que afirme que todos los caracteres en el archivo (o en los primeros 500 bytes si lo desea) están en un conjunto de bytes que son conocido bueno.

Teóricamente, solo consultar los primeros cientos de bytes de un archivo podría generar problemas si se tratara de un archivo compuesto (ej. Texto con imágenes incrustadas), pero en la práctica sospecho que cada archivo tendrá datos de encabezado binarios al principio, entonces probablemente estés bien.

0
  1. Ignoras lo que read() devuelve, ¿y si los archivos tienen menos de 500 bytes?
  2. Cuando devuelve falso, no cierra el archivo.
  3. Al convertir byte en char, supone que su archivo es ASCII de 7 bits.
0

Esto no funcionaría con los paquetes de instalación jdk para linux o solaris.tienen un inicio de script de shell y luego un blob de datos bi.

¿por qué no comprobar el tipo de mimo utilizando una biblioteca como jMimeMagic (http://http://sourceforge.net/projects/jmimemagic/) y se basa en el tipo de mimet de cómo manejar el archivo.

3
  1. falla mal si tamaño del archivo es de menos de 500 bytes

  2. La línea char it = (char) thisByte; es conceptualmente dudosa, se mezcla bytes y CHARS conceptos, es decir. asume implícitamente que la codificación es de un byte = un carácter (ellos, excluye codificaciones unicode). En particular, falla si el archivo está codificado en UTF-16.

  3. El retorno dentro del bucle (práctica de la práctica levemente incorrecta) se olvida de cerrar el archivo.

Cuestiones relacionadas