سؤال

كنت أتساءل فقط كيف يقوم معظم الأشخاص بإحضار نوع mime من ملف في Java؟لقد قمت حتى الآن بتجربة استخدامين: JMimeMagic & Mime-Util.

الأول أعطاني استثناءات في الذاكرة، والثاني لا يغلق تدفقاته بشكل صحيح.كنت أتساءل فقط عما إذا كان لدى أي شخص آخر طريقة/مكتبة استخدمها وعمل بشكل صحيح؟

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

المحلول

في Java 7 يمكنك الآن فقط استخدام Files.probeContentType(path).

نصائح أخرى

للأسف،

mimeType = file.toURL().openConnection().getContentType();

لا يعمل، لأن هذا الاستخدام لعنوان URL يترك الملف مقفلاً، بحيث لا يمكن حذفه على سبيل المثال.

ومع ذلك، لديك هذا:

mimeType= URLConnection.guessContentTypeFromName(file.getName());

وأيضًا ما يلي، والذي يتمتع بميزة تجاوز مجرد استخدام امتداد الملف، وإلقاء نظرة خاطفة على المحتوى

InputStream is = new BufferedInputStream(new FileInputStream(file));
mimeType = URLConnection.guessContentTypeFromStream(is);
 //...close stream

ومع ذلك، كما يقترح التعليق أعلاه، فإن الجدول المدمج لأنواع mime محدود للغاية، ولا يشمل، على سبيل المثال، MSWord وPDF.لذا، إذا كنت تريد التعميم، فستحتاج إلى تجاوز المكتبات المضمنة، باستخدام Mime-Util، على سبيل المثال (وهي مكتبة رائعة، تستخدم كلاً من امتداد الملف والمحتوى).

تعد JAF API جزءًا من JDK 6.ينظر الى javax.activation طَرد.

الطبقات الأكثر إثارة للاهتمام هي javax.activation.MimeType - حامل نوع MIME فعلي - و javax.activation.MimetypesFileTypeMap - الفئة التي يمكن لمثيلها تحليل نوع MIME كسلسلة لملف:

String fileName = "/path/to/file";
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();

// only by file name
String mimeType = mimeTypesMap.getContentType(fileName);

// or by actual File instance
File file = new File(fileName);
mimeType = mimeTypesMap.getContentType(file);

مع أباتشي تيكا تحتاج فقط ثلاثة أسطر من التعليمات البرمجية:

File file = new File("/path/to/file");
Tika tika = new Tika();
System.out.println(tika.detect(file));

إذا كان لديك وحدة تحكم رائعة، فما عليك سوى لصق هذا الرمز وتشغيله للعب به:

@Grab('org.apache.tika:tika-core:1.14')
import org.apache.tika.Tika;

def tika = new Tika()
def file = new File("/path/to/file")
println tika.detect(file)

ضع في اعتبارك أن واجهات برمجة التطبيقات الخاصة به غنية، ويمكنه تحليل "أي شيء".اعتبارًا من tika-core 1.14، لديك:

String  detect(byte[] prefix)
String  detect(byte[] prefix, String name)
String  detect(File file)
String  detect(InputStream stream)
String  detect(InputStream stream, Metadata metadata)
String  detect(InputStream stream, String name)
String  detect(Path path)
String  detect(String name)
String  detect(URL url)

يرى أبيدوكس للمزيد من المعلومات.

أباتشي تيكا العروض في تيكا النواة اكتشاف نوع التمثيل الصامت بناءً على العلامات السحرية في بادئة الدفق. tika-core لا يجلب تبعيات أخرى، مما يجعله خفيف الوزن مثل الذي لا تتم صيانته حاليًا أداة الكشف عن نوع Mime.

مثال بسيط للتعليمات البرمجية (Java 7)، باستخدام المتغيرات theInputStream و theFileName

try (InputStream is = theInputStream;
        BufferedInputStream bis = new BufferedInputStream(is);) {
    AutoDetectParser parser = new AutoDetectParser();
    Detector detector = parser.getDetector();
    Metadata md = new Metadata();
    md.add(Metadata.RESOURCE_NAME_KEY, theFileName);
    MediaType mediaType = detector.detect(bis, md);
    return mediaType.toString();
}

يرجى ملاحظة أنه لا يمكن استخدام MediaType.detect(...) مباشرة (تيكا-1120).يتم توفير المزيد من التلميحات في https://tika.apache.org/0.10/detection.html.

إذا كنت مطور Android، فيمكنك استخدام فئة الأداة المساعدة android.webkit.MimeTypeMap الذي يقوم بتعيين أنواع MIME لامتدادات الملفات والعكس.

قد يساعدك مقتطف التعليمات البرمجية التالي.

private static String getMimeType(String fileUrl) {
    String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}

من com.roseindia:

FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor("alert.gif");

إذا كنت عالقًا مع Java 5-6 ثم فئة المرافق هذه من servoy المنتج مفتوح المصدر.

ما عليك سوى هذه الوظيفة

public static String getContentType(byte[] data, String name)

يقوم بفحص البايتات الأولى من المحتوى وإرجاع أنواع المحتوى بناءً على هذا المحتوى وليس حسب امتداد الملف.

كنت أتساءل فقط كيف يقوم معظم الأشخاص بإحضار نوع mime من ملف في Java؟

لقد نشرت بلدي SimpleMagic حزمة Java التي تسمح بتحديد نوع المحتوى (نوع mime) من الملفات ومصفوفات البايت.إنه مصمم لقراءة وتشغيل الملفات السحرية لأوامر Unix file(1) التي تعد جزءًا من معظم تكوينات نظام التشغيل Unix.

لقد حاولت أباتشي تيكا لكنه كذلك ضخم مع طن من التبعيات، URLConnection لا يستخدم بايت من الملفات، و MimetypesFileTypeMap كما ينظر فقط إلى أسماء الملفات.

باستخدام SimpleMagic يمكنك القيام بشيء مثل:

// create a magic utility using the internal magic file
ContentInfoUtil util = new ContentInfoUtil();
// if you want to use a different config file(s), you can load them by hand:
// ContentInfoUtil util = new ContentInfoUtil("/etc/magic");
...
ContentInfo info = util.findMatch("/tmp/upload.tmp");
// or
ContentInfo info = util.findMatch(inputStream);
// or
ContentInfo info = util.findMatch(contentByteArray);

// null if no match
if (info != null) {
   String mimeType = info.getMimeType();
}

للمشاركة بمبلغ 5 سنتات:

ليرة تركية، د

أنا أستعمل MimetypesFileTypeMap وأضف أي ملف mime غير موجود وأحتاج إليه على وجه التحديد، في ملف mime.types.

والآن القراءة الطويلة:

أولا وقبل كل شيء، قائمة أنواع MIME هي ضخم, ، انظر هنا: https://www.iana.org/signments/media-types/media-types.xhtml

أحب استخدام المرافق القياسية التي تقدمها JDK أولاً، وإذا لم ينجح ذلك، سأذهب وأبحث عن شيء آخر.

تحديد نوع الملف من امتداد الملف

منذ 1.6، تحتوي Java على MimetypesFileTypeMap، كما هو موضح في إحدى الإجابات أعلاه، وهي أبسط طريقة لتحديد نوع mime:

new MimetypesFileTypeMap().getContentType( fileName );

في تنفيذ الفانيليا، هذا لا يفعل الكثير (أي.إنه يعمل مع .html ولكنه لا يعمل مع .png).ومع ذلك، من السهل جدًا إضافة أي نوع محتوى قد تحتاجه:

  1. قم بإنشاء ملف باسم "mime.types" في مجلد META-INF في مشروعك
  2. أضف سطرًا لكل نوع mime تحتاجه ولا يوفر التنفيذ الافتراضي (هناك المئات من أنواع mime والقائمة تنمو مع مرور الوقت).

إدخالات الأمثلة لملفات png وjs ستكون:

image/png png PNG
application/javascript js

للحصول على تنسيق ملف mime.types، راجع المزيد من التفاصيل هنا: https://docs.Oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html

تحديد نوع الملف من محتوى الملف

منذ 1.7، جافا لديها java.nio.file.spi.FileTypeDetector, ، الذي يحدد واجهة برمجة التطبيقات القياسية لتحديد نوع الملف طريقة التنفيذ محددة.

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

Files.probeContentType(Paths.get("either file name or full path goes here"));

يوفر تعريف واجهة برمجة التطبيقات تسهيلات تدعم تحديد نوع mime للملف من اسم الملف أو من محتوى الملف (البايت السحري).ذلك هو السبب نوع مسبار المحتوى () تطرح الطريقة IOException، في حالة استخدام تطبيق واجهة برمجة التطبيقات هذه للمسار المقدم لها لمحاولة فتح الملف المرتبط به فعليًا.

مرة أخرى، الفانيليا تطبيق هذا (الذي يأتي مع JDK) يترك الكثير مما هو مرغوب فيه.

في عالم مثالي ما في مجرة ​​بعيدة جدًا، كل هذه المكتبات التي تحاول حل هذه المشكلة من نوع الملف إلى التمثيل الصامت ستنفذ ببساطة java.nio.file.spi.FileTypeDetector, ، يمكنك إسقاط ملف jar الخاص بمكتبة التنفيذ المفضلة في مسار الفصل الخاص بك وسيكون هذا هو الحال.

في العالم الحقيقي، حيث تحتاج إلى قسم TL,DR، يجب أن تجد المكتبة التي تحتوي على معظم النجوم بجوار اسمها وتستخدمها.في هذه الحالة بالذات، لا أحتاج إلى واحدة (حتى الآن؛)).

لقد جربت عدة طرق للقيام بذلك، بما في ذلك الطرق الأولى التي قالها @Joshua Fox.لكن البعض لا يتعرف على أنواع mimetypes المتكررة مثل ملفات PDF، والبعض الآخر لا يمكن الوثوق به مع الملفات المزيفة (حاولت استخدام ملف RAR بامتداد تم تغييره إلى TIF).الحل الذي وجدته، كما قال @Joshua Fox بطريقة سطحية، هو الاستخدام MimeUtil2, ، مثله:

MimeUtil2 mimeUtil = new MimeUtil2();
mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();

من الأفضل استخدام التحقق من طبقتين لتحميل الملفات.

أولاً يمكنك التحقق من mimeType والتحقق من صحته.

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

في الربيع ملف متعدد الأجزاء ملف؛

org.springframework.web.multipart.MultipartFile

file.getContentType();

هذه هي أبسط طريقة وجدتها للقيام بذلك:

byte[] byteArray = ...
InputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray));
String mimeType = URLConnection.guessContentTypeFromStream(is);

إذا كنت تعمل على نظام التشغيل Linux، فهناك سطر أوامر file --mimetype:

String mimetype(file){

   //1. run cmd
   Object cmd=Runtime.getRuntime().exec("file --mime-type "+file);

   //2 get output of cmd , then 
    //3. parse mimetype
    if(output){return output.split(":")[1].trim(); }
    return "";
}

ثم

mimetype("/home/nyapp.war") //  'application/zip'

mimetype("/var/www/ggg/au.mp3") //  'audio/mp3'

بعد تجربة العديد من المكتبات الأخرى، استقريت على استخدام mime-util.

<groupId>eu.medsea.mimeutil</groupId>
      <artifactId>mime-util</artifactId>
      <version>2.1.3</version>
</dependency>

File file = new File("D:/test.tif");
MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
Collection<?> mimeTypes = MimeUtil.getMimeTypes(file);
System.out.println(mimeTypes);
public String getFileContentType(String fileName) {
    String fileType = "Undetermined";
    final File file = new File(fileName);
    try
    {
        fileType = Files.probeContentType(file.toPath());
    }
    catch (IOException ioException)
    {
        System.out.println(
                "ERROR: Unable to determine file type for " + fileName
                        + " due to exception " + ioException);
    }
    return fileType;
}

يمكنك القيام بذلك بسطر واحد فقط: MimetypesFileTypeMap().getContentType(ملف جديد("filename.ext")).انظر إلى رمز الاختبار الكامل (Java 7):

import java.io.File;
import javax.activation.MimetypesFileTypeMap;
public class MimeTest {
    public static void main(String a[]){
         System.out.println(new MimetypesFileTypeMap().getContentType(
           new File("/path/filename.txt")));
    }
}

ينتج هذا الرمز الإخراج التالي: نص عادي

File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top