문제

즉, 아카이브(jar/rar/etc.) 파일과 텍스트(xml/txt, 인코딩 독립적) 파일을 어떻게 구분할 수 있습니까?

도움이 되었습니까?

해결책

보장 된 방법은 없지만 몇 가지 가능성이 있습니다.

1) 파일에서 헤더를 찾으십시오. 불행히도, 헤더는 파일 별이므로 RAR 파일이라는 것을 알 수 있지만 텍스트인지 바이너리인지에 대한 일반적인 대답을 얻지 못할 수도 있습니다.

2) 문자 수와 비 특가자 유형을 계산하십시오. 텍스트 파일은 주로 알파벳순 문자이며 이진 파일, 특히 RAR, Zip 등과 같은 압축 파일은 바이트가 더 균등하게 표현되는 경향이 있습니다.

3) 정기적으로 반복되는 신형 패턴을 찾으십시오.

다른 팁

운영 file -bi {filename}. 반환하는 것이 'Text/'로 시작하면 이진적이지 않으며 그렇지 않으면 그렇지 않습니다. ;-)

나는 이것을 만들었다. 조금 간단하지만 라틴어 기반 언어의 경우 비율 조정과 함께 잘 작동해야합니다.

/**
 *  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;
}

살펴보십시오 jmimemagic 도서관.

Jmimemagic은 마임 유형의 파일 또는 스트림을 결정하기위한 Java 라이브러리입니다.

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;
        }
    }

이 코드를 사용했으며 영어와 독일어 텍스트에 잘 작동합니다.

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;
}

파일이 0x09(탭), 0x0A(줄 바꿈), 0x0C(폼 피드), 0x0D(캐리지 리턴) 또는 0x20~0x7E 바이트로 구성된 경우 이는 아마도 ASCII 텍스트일 것입니다.

파일에 위의 세 문자를 제외하고 0x00부터 0x1F까지의 다른 ASCII 제어 문자가 포함되어 있으면 아마도 이진 데이터일 것입니다.

UTF-8 텍스트는 상위 비트가 있는 모든 바이트에 대해 매우 구체적인 패턴을 따르지만 ISO-8859-1과 같은 고정 길이 인코딩은 그렇지 않습니다.UTF-16에는 널 바이트(0x00)가 포함될 수 있지만 다른 모든 위치에만 포함될 수 있습니다.

다른 것에 대해서는 더 약한 경험적 방법이 필요합니다.

알려주기 위해, 나는 상당히 다른 길을 선택했습니다. 제 경우에는 2 가지 유형의 파일 만 있습니다. 주어진 파일이 바이너리 파일 일 가능성이 높습니다. 그래서

  1. 그 파일이 이진이라고 가정하고,해야 할 일을 시도하십시오 (예 : deserialize).
  2. 예외를 잡습니다
  3. 파일을 텍스트로 취급하십시오
  4. 실패하면 파일 자체에 문제가 있습니다.

당신은 시도 할 수 있습니다 드로이드 도구.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top