انتقل إلى المحتوى

ابحث في CooLWJ

选择搜索范围,输入关键词后按回车。

اللغة

الحصول على نوع الملف باستخدام File في Java

في تطوير Java، كثيرًا ما نحتاج إلى تحديد نوع الملف؛ ففي وظيفة رفع الملفات مثلًا، نحتاج إلى التحقق من أن الملف الذي يرفعه المستخدم من النوع المطلوب. تشرح هذه المقالة بالتفصيل طرق الحصول على نوع الملف باستخدام Java.

أولًا、تحديد نوع الملف باستخدام امتداده

الطريقة الأكثر شيوعًا لتحديد نوع الملف هي الاعتماد على امتداده. لمعظم الملفات امتداد محدد في نظام التشغيل، فمثلًا يكون امتداد الملفات النصية عادةً .txt، عادةً ما يكون امتداد ملف الصورة.jpg أو.png وما إلى ذلك.

الحصول على امتداد ملف باستخدام برنامج Java أمر بسيط جدًا، إذ يكفي استخدام String الخاص بالفئة substring تكفي هذه الطريقة، كما توضح الشيفرة التالية:

public static String getFileExtension(File file) {
    String fileName = file.getName();
    if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    } else {
        return "";
    }
}


تستقبل هذه الطريقة File الكائن بوصفه وسيطًا، ثم استخدام lastIndexOf تحدد الدالة موضع آخر نقطة في اسم الملف، أي موضع بداية الامتداد، ثم تستخدم substring تستخرج الدالة سلسلة امتداد الملف وتعيدها. وإذا لم يكن للملف امتداد، فإنها تعيد سلسلة فارغة.

يمكن اختبار هذه الطريقة باستخدام الشيفرة التالية:

File file = new File("C:/path/to/file.txt");
String extension = getFileExtension(file);
System.out.println(extension);


نتيجة التشغيل هي:

txt

لتحديد نوع الملف بهذه الطريقة المزايا التالية:

  • بسيط وسهل الاستخدام، وتنفيذه البرمجي موجز.

  • ينجح مع الغالبية العظمى من الملفات، لأن الغالبية العظمى منها لها امتدادات.

ومع ذلك، لهذه الطريقة بعض العيوب أيضًا:

  • قد يُغيَّر امتداد الملف، مما يؤدّي إلى نتيجة تحقّق خاطئة.

  • بعض الملفات لا تحمل لاحقة، مثل الملفات التنفيذية التي لا امتداد لها.

لتحديد نوع الملف بدقة أكبر، يمكننا الاستعانة بالرقم السحري للملف.

صورة توضيحية لموضوع التعرف على نوع الملف باستخدام Java

ثانيًا、تحديد نوع الملف باستخدام الأرقام السحرية للملفات

الرقم السحري للملف هو مجموعة من البايتات المحددة ضمن البايتات الأولى من الملف، وتُستخدم للتعرف على نوعه. ومن خلال التعرف على الرقم السحري للملف، يمكننا تحديد نوعه بدقة، دون التأثر بامتداد اسمه.

في Java، يمكن الحصول على الرقم السحري للملف بقراءة بياناته الثنائية.

2.1 قراءة البيانات الثنائية للملف

يمكننا استخدام FileInputStream لقراءة البيانات الثنائية للملف باستخدام هذا الصنف. ستُرجع الطريقة التالية مصفوفة بايتات تحتوي على البيانات الثنائية للملف:

public static byte[] readFileToByteArray(File file) throws IOException {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        byte[] data = new byte[(int)file.length()];
        fis.read(data);
        return data;
    } finally {
        if (fis != null) {
            fis.close();
        }
    }
 }


استخدمت الطريقة أعلاه FileInputStream لفتح الملف وقراءة البيانات وتخزينها في مصفوفة بايتات. يُرجى الانتباه إلى أنه بعد إتمام قراءة الملف، يلزم استدعاء close لإغلاق تدفق الملف وتحرير موارد النظام باستخدام هذه الطريقة.

2.2 استخدام الأرقام السحرية للملفات لتحديد نوع الملف

بعد الحصول على البيانات الثنائية للملف، يمكننا تحديد نوعه. فلكل نوع من الملفات رقم سحري خاص يمكن الاعتماد عليه لتحديد نوع الملف. وفيما يلي الأرقام السحرية لبعض أنواع الملفات الشائعة، وطرق التحقق المقابلة لها:

  • الرقم السحري للملفات النصية(.txt)هو EF BB BF(يوجد تسلسل البايتات هذا في بداية الملف المرمّز بصيغة UTF-8),ويمكن استخدام الطريقة التالية للتحقّق:

    public static boolean isTextFile(byte[] data) {
      if (data.length >= 3 && data[0] == -17 && data[1] == -69 && data[2] == -65) {
          return true;
      }
      return false;
    }


  • الرقم السحري لصور JPEG(.jpg)هو FF D8 FF، يمكن استخدام الطرق التالية للتحقق:

    public static boolean isJPEGFile(byte[] data) {
      if (data.length >= 3 && data[0] == -1 && data[1] == -40 && data[2] == -1) {
          return true;
      }
      return false;
     }


  • الرقم السحري لصور PNG(.png)هو 89 50 4E 47 0D 0A 1A 0A، يمكن استخدام الطرق التالية للتحقق:

    public static boolean isPNGFile(byte[] data) {
      if (data.length >= 8 && data[0] == -119 && data[1] == 80 && data[2] == 78 && data[3] == 71 &&
          data[4] == 13 && data[5] == 10 && data[6] == 26 && data[7] == 10) {
          return true;
      }
      return false;
    }


يمكن إضافة مزيد من أنواع الملفات وطرق التحقق من الأرقام السحرية المقابلة لها حسب الحاجة.

2.3 مثال كامل

فيما يلي مثال كامل يوضّح كيفية استخدام الأرقام السحرية للملفات لتحديد نوع الملف:

import java.io.File;import java.io.FileInputStream;import java.io.IOException;public class FileTypeChecker {
    public static void main(String[] args) {
        File file = new File("C:/path/to/file.jpg");
        try {
            byte[] data = readFileToByteArray(file);
            if (isJPEGFile(data)) {
                System.out.println("This is a JPEG file.");
            } else if (isPNGFile(data)) {
                System.out.println("This is a PNG file.");
            } else if (isTextFile(data)) {
                System.out.println("This is a text file.");
            } else {
                System.out.println("Unknown file type.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static byte[] readFileToByteArray(File file) throws IOException {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            byte[] data = new byte[(int)file.length()];
            fis.read(data);
            return data;
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }

    public static boolean isTextFile(byte[] data) {
        if (data.length >= 3 && data[0] == -17 && data[1] == -69 && data[2] == -65) {
            return true;
        }
        return false;
    }

    public static boolean isJPEGFile(byte[] data) {
        if (data.length >= 3 && data[0] == -1 && data[1] == -40 && data[2] == -1) {
            return true;
        }
        return false;
    }

    public static boolean isPNGFile(byte[] data) {
        if (data.length >= 8 && data[0] == -119 && data[1] == 80 && data[2] == 78 && data[3] == 71 &&
            data[4] == 13 && data[5] == 10 && data[6] == 26 && data[7] == 10) {
            return true;
        }
        return false;
    }
 }


تحدّد الشيفرة النموذجية أعلاه نوع الملف بناءً على رقمه السحري، وتُخرج النتيجة المقابلة.

ثالثًا، استخدام مكتبة خارجية لتحديد نوع الملف

إلى جانب الطرق المذكورة أعلاه، يمكن أيضًا استخدام مكتبات من جهات خارجية لتحديد نوع الملف. وتتوفر في Java بعض المكتبات المفتوحة المصدر من جهات خارجية التي تساعدنا على معرفة أنواع الملفات بسهولة أكبر.

3.1 Tika

Tika  هو مشروع تابع لمؤسسة Apache Software Foundation، يوفر مكتبة Java مفتوحة المصدر لتحليل تنسيقات ملفات متنوعة، تشمل النصوص والصور والصوت والفيديو وغيرها. ويمكن باستخدام Tika استخراج البيانات الوصفية للملفات، بما فيها نوع الملف.

أولًا، يجب إضافة اعتمادية مكتبة Tika. إذا كنت تستخدم Maven لبناء المشروع، فيمكنك في pom.xml أضف التبعيات التالية إلى الملف:

<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>1.27</version>
</dependency>


بعد ذلك، يمكنك استخدام الشيفرة التالية للحصول على نوع الملف:

import org.apache.tika.Tika;
public class FileTypeChecker {
    public static void main(String[] args) {
        Tika tika = new Tika();
        try {
            File file = new File("C:/path/to/file.jpg");
            String fileType = tika.detect(file);
            System.out.println("File type: " + fileType);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


سيؤدي تشغيل الشيفرة أعلاه إلى إخراج نوع الملف.

يستخدم Tika طرقًا متنوعة للتعرف على أنواع الملفات، بما فيها امتداد الملف والرقم السحري وغيرها. ويدعم أيضًا كواشف مخصصة، تتيح إضافة قواعد مخصصة لتحديد نوع الملف بحسب الحاجة.

3.2 FileTypeDetector

توفر Java واجهة API قياسية لاكتشاف أنواع الملفات، وهي FileTypeDetector الواجهة و ProbeContentType أصناف. ومن خلال تنفيذ هذه الواجهة، يمكن تخصيص كاشف لأنواع الملفات.

فيما يلي مثال على كاشف مخصص لأنواع الملفات:

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.spi.FileTypeDetector;

public class CustomFileTypeDetector extends FileTypeDetector {
    @Override
    public String probeContentType(Path path) throws IOException {
        String extension = getFileExtension(path.toFile());
        if ("txt".equals(extension)) {
            return "text/plain";
        } else if ("jpg".equals(extension) || "jpeg".equals(extension)) {
            return "image/jpeg";
        } else if ("png".equals(extension)) {
            return "image/png";
        } else {
            return null;
        }
    }

    private String getFileExtension(File file) {
        String fileName = file.getName();
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        } else {
            return "";
        }
    }
  }

في هذا المثال، نحدد نوع الملف بناءً على امتداده، ونعيد نوع MIME الموافق له.

لاستخدام كاشف مخصص لأنواع الملفات، أضف الشيفرة التالية عند نقطة دخول البرنامج:

File file = new File("C:/path/to/file.jpg");
Path path = file.toPath();
String fileType = Files.probeContentType(path);
System.out.println("File type: " + fileType);

سيؤدي تشغيل الشيفرة أعلاه إلى إخراج نوع الملف.

يرجى الانتباه إلى أن هذه الطريقة المعتمدة على الامتداد قد لا تكون دقيقة بما يكفي لبعض أنواع الملفات الخاصة، مثل الملفات التنفيذية التي لا تحمل امتدادًا، لذا يُفضَّل استخدام الطريقة القائمة على الأرقام السحرية للملفات التي شُرحت سابقًا.

رابعًا، الخلاصة

عرضت هذه المقالة عدة طرائق للحصول على نوع الملف في Java. يمكن تحديد نوع الملف من امتداده، أو من رقمه السحري. ويتيح استخدام مكتبات خارجية مثل Tika الحصول على نوع الملف بسهولة أكبر. أما أنواع الملفات الخاصة، فيمكن تحديدها بدقة باستخدام كاشف مخصص لأنواع الملفات.

يعتمد اختيار الطريقة المناسبة لتحديد نوع الملف على سيناريو التطبيق ومتطلباته المحددة. وفي التطوير الفعلي، ينبغي اختيار أنسب طريقة للتحقق بناءً على خصائص الملف والمتطلبات، مع مراعاة قابلية التوسّع والتوافق.


التعليقات

جارٍ الإرسال

اختر المظهر المفضل

يُطبّق المظهر على الموقع كله.