Pregunta

Es decir, ¿cómo le diría a un archivo (jar / rar / etc.) de un archivo textual (xml / txt, independiente de la codificación)?

¿Fue útil?

Solución

No hay una forma garantizada, pero aquí hay un par de posibilidades:

1) Busque un encabezado en el archivo. Desafortunadamente, los encabezados son específicos de un archivo, por lo que si bien puede descubrir que es un archivo RAR, no obtendrá la respuesta más genérica de si es de texto o binario.

2) Cuente el número de caracteres frente a los tipos sin caracteres. Los archivos de texto serán en su mayoría caracteres alfabéticos, mientras que los archivos binarios, especialmente los comprimidos como rar, zip y similares, tenderán a tener bytes representados de manera más equitativa.

3) Busque un patrón de líneas nuevas que se repita regularmente.

Otros consejos

Ejecuta file -bi {filename} . Si lo que devuelve comienza con 'texto /', entonces no es binario, de lo contrario lo es. ;-)

Hice este. Un poco más simple, pero para los lenguajes basados ??en latín, debería funcionar bien, con el ajuste de proporción.

/**
 *  Guess whether given file is binary. Just checks for anything under 0x09.
 */
public static boolean isBinaryFile(File f) throws FileNotFoundException, IOException {
    FileInputStream in = new FileInputStream(f);
    int size = in.available();
    if(size > 1024) size = 1024;
    byte[] data = new byte[size];
    in.read(data);
    in.close();

    int ascii = 0;
    int other = 0;

    for(int i = 0; i < data.length; i++) {
        byte b = data[i];
        if( b < 0x09 ) return true;

        if( b == 0x09 || b == 0x0A || b == 0x0C || b == 0x0D ) ascii++;
        else if( b >= 0x20  &&  b <= 0x7E ) ascii++;
        else other++;
    }

    if( other == 0 ) return false;

    return 100 * other / (ascii + other) > 95;
}

Eche un vistazo a la biblioteca JMimeMagic

  

jMimeMagic es una biblioteca de Java para   determinar el tipo de archivos MIME o   arroyos.

Uso de la clase de archivos Java 7 http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType (java.nio.file.Path)

boolean isBinaryFile(File f) throws IOException {
        String type = Files.probeContentType(f.toPath());
        if (type == null) {
            //type couldn't be determined, assume binary
            return true;
        } else if (type.startsWith("text")) {
            return false;
        } else {
            //type isn't text
            return true;
        }
    }

Utilicé este código y funciona bastante bien para el texto en inglés y alemán:

private boolean isTextFile(String filePath) throws Exception {
    File f = new File(filePath);
    if(!f.exists())
        return false;
    FileInputStream in = new FileInputStream(f);
    int size = in.available();
    if(size > 1000)
        size = 1000;
    byte[] data = new byte[size];
    in.read(data);
    in.close();
    String s = new String(data, "ISO-8859-1");
    String s2 = s.replaceAll(
            "[a-zA-Z0-9ßöäü\\.\\*!\"§\\$\\%&/()=\\?@~'#:,;\\"+
            "+><\\|\\[\\]\\{\\}\\^°²³\\\\ \\n\\r\\t_\\-`´âêîô"+
            "ÂÊÔÎáéíóàèìòÁÉÍÓÀÈÌÒ©‰¢£¥€±¿»«¼½¾™ª]", "");
    // will delete all text signs

    double d = (double)(s.length() - s2.length()) / (double)(s.length());
    // percentage of text signs in the text
    return d > 0.95;
}

Si el archivo consta de los bytes 0x09 (tab), 0x0A (salto de línea), 0x0C (feed de formulario), 0x0D (retorno de carro) o 0x20 a través de 0x7E, es probable que sea un texto ASCII.

Si el archivo contiene cualquier otro carácter de control ASCII, 0x00 a 0x1F excluyendo los tres anteriores, es probable que sean datos binarios.

El texto UTF-8 sigue un patrón muy específico para cualquier byte con el bit de orden superior, pero las codificaciones de longitud fija como ISO-8859-1 no lo hacen. UTF-16 puede contener frecuentemente el byte nulo (0x00), pero solo en cualquier otra posición.

Necesitarías una heurística más débil para cualquier otra cosa.

Para dejarte saber, he elegido un camino muy diferente. En mi caso, solo hay 2 tipos de archivos, las posibilidades de que un archivo dado sea binario son altas. Así que

  1. suponga que el archivo es binario, intente hacer lo que debe hacerse (por ejemplo, deserializar)
  2. excepción de captura
  3. tratar el archivo como textual
  4. si eso falla, algo está mal con el archivo en sí

Puede probar la herramienta DROID .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top