سؤال

على وجه التحديد، كيف يمكنك التمييز بين ملف أرشيف (jar/rar/etc.) من ملف نصي (xml/txt، مستقل عن التشفير)؟

هل كانت مفيدة؟

المحلول

ولا توجد طريقة مضمونة، ولكن هنا عدة احتمالات:

1) ابحث عن رأس على الملف. للأسف، ورؤوس هي ملف معين، وذلك في حين أنك قد تكون قادرة على معرفة أنه ملف RAR، فإنك لن تحصل على الجواب أكثر عمومية النظر عما إذا كانت نصية أو ثنائي.

2) حساب عدد من الطابع مقابل أنواع غير أحرف. سوف ملفات نصية تكون الأحرف الأبجدية في الغالب حين الملفات الثنائية - وخاصة تلك مضغوط مثل رر، والرمز البريدي، وهذا - سوف تميل إلى أن تكون أكثر بايت بالتساوي ممثلة

و3) ابحث عن نمط تكرار بانتظام من أسطر جديدة.

نصائح أخرى

وتشغيل file -bi {filename}. إذا كل ما يعود يبدأ مع "النص / '، ثم انها غير ثنائي، وإلا هو عليه. ؛ -)

وأنا جعلت هذا واحد. وهناك القليل أبسط، ولكن للغات أساس اللاتينية، ينبغي أن تعمل بشكل جيد، مع تعديل نسبة.

/**
 *  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 هي مكتبة جافا ل   تحديد نوع MIME من الملفات أو   مجاري المياه.

وباستخدام Java 7 الدرجة الملفات <وأ href = "http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType(java.nio.file.Path ) "يختلط =" noreferrer "> 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.

إذا كان الملف يحتوي على أي حرف تحكم ASCII الآخرين، 0x00 خلال 0x1F باستثناء الثلاثة المذكورة أعلاه، فإن ذلك ربما البيانات الثنائية.

وUTF-8 نص يتبع نمطا محددا للغاية بالنسبة لأي بايت مع ارتفاع قليلا النظام، ولكن ترميزات ذات طول ثابت مثل ISO-8859-1 لا. يمكن أن تحتوي UTF-16 في كثير من الأحيان البايت فارغة (0x00)، ولكن فقط في كل موقف آخر.

وكنت في حاجة إلى الكشف عن مجريات الأمور أضعف لأي شيء آخر.

فقط لأعلمك، لقد اخترت طريقًا مختلفًا تمامًا.في حالتي، يوجد نوعان فقط من الملفات، ومن المرجح أن يكون أي ملف ثنائيًا.لذا

  1. افترض أن هذا الملف ثنائي، حاول القيام بما يفترض القيام به (على سبيل المثال.إلغاء التسلسل)
  2. استثناء الصيد
  3. التعامل مع الملف على أنه نصي
  4. إذا فشل ذلك، هناك خطأ ما في الملف نفسه

هل يمكن أن تحاول DROID الأداة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top