sourcecode

파일의 미디어 타입(MIME 타입)을 취득하는 방법

copyscript 2022. 8. 19. 21:02
반응형

파일의 미디어 타입(MIME 타입)을 취득하는 방법

Java를 사용하여 파일에서 미디어 유형(MIME 유형)을 가져오려면 어떻게 해야 합니까?지금까지 JMime Magic & Mime-Util을 먹어봤어요.첫 번째는 메모리 예외를 주고 두 번째는 스트림을 제대로 닫지 않습니다.

(확장자뿐만 아니라) 실제 유형을 결정하기 위해 파일을 어떻게 조사하시겠습니까?

Java 7에서는 를 사용할 수 있게 되었습니다.

불행하게도,

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(파일 확장자와 콘텐츠를 모두 사용하는 훌륭한 라이브러리)을 사용하여 기본 제공 라이브러리를 넘어설 필요가 있습니다.

Apache Tika에서는 3줄의 코드만 있으면 됩니다.

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)

API가 풍부하므로 "모든 것"을 해석할 수 있습니다.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)

상세한 것에 대하여는, 「apidocs」를 참조해 주세요.

6의 입니다.JAF API의 JDK 6을 .javax.activation★★★★★★★★★★★★★★★★★★.

흥미있는 은 ★★★★★★★★★★★★★★★★★★★★★★★★☆javax.activation.MimeType홀더 - 및 - MIME 유형 홀더 -javax.activation.MimetypesFileTypeMap- a file "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);

Apache Tika는 tika-core에서 스트림 프리픽스의 매직마커를 기반으로 한 MIME 유형 탐지를 제공합니다. tika-core는 다른 종속성을 가져오지 않으므로 현재 유지보수가 되지 않은 MIME 유형 탐지 유틸리티만큼 가볍습니다.

'Java 7'을 한 간단한 코드 예 7), '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(...)직접 사용할 수 없습니다(TIKA-1120).더 많은 힌트는 https://tika.apache.org/1.24/detection.html에서 제공됩니다.

Android를 할 수 .android.webkit.MimeTypeMapMIME 타입을 파일 확장자에 매핑하거나 파일 확장자를 매핑합니다.

다음 코드 조각이 도움이 될 수 있습니다.

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

로즈인디아에서:

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

Java 5-6을 사용하는 경우유틸리티 클래스는 servoy 오픈소스 제품의 것입니다.

이 기능만 있으면 됩니다.

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

콘텐츠의 첫 번째 바이트를 검색하여 파일 확장자가 아닌 해당 콘텐츠에 따라 콘텐츠유형을 반환합니다.

대부분의 사람들이 자바에서 어떻게 마임타입을 가져오는지 궁금해서요.

파일과 바이트 배열에서 콘텐츠 유형(마임 유형)을 판별할 수 있는 SimpleMagic Java 패키지를 공개했습니다.대부분의 Unix OS 구성에 포함된 Unix file (1) 명령어 매직파일을 읽고 실행할 수 있도록 설계되었습니다.

Apache Tika를 시도해봤지만 의존도가 엄청나네요.URLConnection하지 않습니다 파일의 바이트는 사용하지 않습니다.MimetypesFileTypeMap또한 파일 이름만 봅니다.

Simple Magic을 사용하면 다음과 같은 작업을 수행할 수 있습니다.

// 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센트를 기부하려면:

TL, DR

Mimetypes File Type Map을 사용하여 존재하지 않는 모든 MIME을 mime.types 파일에 추가합니다.

그리고 이제, 긴 글귀는 다음과 같습니다.

우선, MIME 타입의 리스트는 매우 넓습니다.https://www.iana.org/assignments/media-types/media-types.xhtml 를 참조해 주세요.

우선 JDK가 제공하는 표준 설비를 이용하고 싶다고 생각하고 있습니다만, 그래도 안 되면 다른 설비를 찾아보겠습니다.

파일 확장자에서 파일 유형 확인

1.6 이후 Java는 위의 답변 중 하나에서 지적된 바와 같이 Mimetpes File Type Map을 가지고 있으며, 이는 MIME 유형을 결정하는 가장 간단한 방법입니다.

new MimetypesFileTypeMap().getContentType( fileName );

vanilla 실장에서는 이것은 그다지 효과가 없습니다(즉, .html에서는 동작하지만 .png에서는 동작하지 않습니다).그러나 필요한 콘텐츠 유형을 추가하는 것은 매우 간단합니다.

  1. 프로젝트의 META-INF 폴더에 'mime.types'라는 이름의 파일을 만듭니다.
  2. 필요한 모든 MIME 유형에 대해 행을 추가합니다. 기본 구현에서는 제공되지 않습니다(시간이 지날수록 수백 개의 MIME 유형과 목록이 늘어납니다).

png 및 js 파일의 예는 다음과 같습니다.

image/png png PNG
application/javascript js

mime.types 파일 형식에 대한 자세한 내용은http://https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html 를 참조해 주세요.

파일 내용에서 파일 유형 결정

1.7 이후 Java에는 java.nio.file.spi가 있습니다.FileTypeDetector: 구현 고유의 방법으로 파일 형식을 결정하기 위한 표준 API를 정의합니다.

파일의 MIME 유형을 가져오려면 파일(Files)을 사용하여 코드 내에서 다음을 수행합니다.

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

API 정의는 파일 이름 또는 파일 내용(매직바이트)에서 파일 MIME 유형을 결정하는 기능을 제공합니다.그렇기 때문에 probeContentType() 메서드는 이 API의 구현에서 제공된 경로를 사용하여 관련된 파일을 실제로 열려고 할 때 IOException을 슬로우합니다.

이것(JDK에 부속된 것)의 vanilla 실장은 부족한 점이 많습니다.

멀리 떨어진 은하계의 어떤 이상적인 세계에서는 이 파일-to-mime 유형의 문제를 해결하려고 하는 모든 라이브러리가 단순히 java.nio.file.spi를 구현합니다.FileTypeDetector는 선호하는 구현 라이브러리의 jar 파일을 클래스 경로에 드롭하면 됩니다.

실제로 TL, DR 섹션이 필요한 경우 이름 옆에 별이 가장 많이 있는 라이브러리를 찾아서 사용해야 합니다.이 경우에는 (아직) 필요 없습니다.

@Joshua Fox가 말한 첫 번째 방법 등 몇 가지 방법을 시도했습니다.그러나 PDF 파일처럼 빈번한 mimetype을 인식하지 못하는 사람도 있고 가짜 파일을 신뢰할 수 없는 사람도 있습니다(확장자가 TIF로 변경된 RAR 파일을 사용해 보았습니다).제가 찾은 솔루션은 @Joshua Fox가 피상적으로 말한 것처럼 다음과 같이 Mime Util2를 사용하는 것입니다.

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

이 작업을 수행하는 가장 간단한 방법은 다음과 같습니다.

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

아파치 티카.

<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-parsers -->
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-parsers</artifactId>
    <version>1.24</version>
</dependency>

그리고 코드 두 줄.

Tika tika=new Tika();
tika.detect(inputStream);

아래 스크린샷

여기에 이미지 설명 입력

단순 및 최적 옵션은 파일 위치에서 내용 MIME 유형을 검색합니다.

이 가져오기 사용

import java.nio.file.Files;
import java.nio.file.Path;

코드

String type = Files.probeContentType(Path.of(imagePath));

파일 업로드에는 2개의 레이어 검증을 사용하는 것이 좋습니다.

먼저 MIME을 확인할 수 있습니다.입력하고 유효성을 확인합니다.

둘째, 파일의 처음 4바이트를 16진수로 변환한 후 매직 수치와 비교해야 합니다.그러면 파일 검증을 확인하는 매우 안전한 방법이 될 것입니다.

이 작업은 한 줄만으로 수행할 수 있습니다.Mimetypes FileTypeMap().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")));
    }
}

이 코드는 text/plain 출력을 생성합니다.

서블릿을 사용하고 있고 서블릿콘텍스트를 사용할 수 있는 경우는, 다음과 같이 사용할 수 있습니다.

getServletContext().getMimeType( fileName );

할 수 것을 찾을 수 없습니다.video/mp4MIME을 사용합니다., 위키피디아는 .00 00 00 18 66 74 79 70 69 73 6F 6D번째 바이트( 번째 바이트)18) 및 all) 。70 후 (7) 이 있는 (7) 후 (7) 변경 후) 유효합니다.mp4files.complete files files files files files files files files.

입니다.URLConnection.guessContentTypeFromStream이지만, 「」, 「」에 커스터마이즈 됩니다.video/mp4.

BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(content));
String mimeType = URLConnection.guessContentTypeFromStream(bis);

// Goes full barbaric and processes the bytes manually
if (mimeType == null){
    // These ints converted in hex ar:
    // 00 00 00 18 66 74 79 70 69 73 6F 6D
    // which are the file signature (magic bytes) for .mp4 files
    // from https://www.wikiwand.com/en/List_of_file_signatures
    // just ctrl+f "mp4"
    int[] mp4_sig = {0, 0, 0, 24, 102, 116, 121, 112};

    bis.reset();
    bis.mark(16);
    int[] firstBytes = new int[8];
    for (int i = 0; i < 8; i++) {
        firstBytes[i] = bis.read();
    }
    // This byte doesn't matter for the file signature and changes
    mp4_sig[3] = content[3];

    bis.reset();
    if (Arrays.equals(firstBytes, mp4_sig)){
        mimeType = "video/mp4";
    }
}

10가지 10가지 에 성공했습니다..mp4files.complete files files files files files files files files.

편집: 이 링크에서는 다양한 유형의 샘플을 찾을 수 있습니다(아직 온라인 상태인 경우).이 비디오들은 제가 소유하고 있지 않습니다.누가 가지고 있는지는 모르겠지만, 위의 코드를 테스트하는 데 도움이 됩니다.

사실 아파치 티카 탐지기는 Tika.detect(File)입니다.Files.probeContentType(path).

예시와 코드 샘플이 포함된 이 훌륭한 빠른 참조를 확인하십시오.

spring MultipartFile 파일에 저장;

org.springframework.web.web.springart.멀티파트 파일

file.getContentType();

파일의 미디어1 유형을 탐지하는 솔루션에는 다음과 같은 부분이 있습니다.

  • 파일 서명 목록(Kessler 목록, Wikipedia 목록Space Maker 목록 참조)
  • 미디어 유형 목록
  • 파일 이름 확장자에 대한 미디어 유형 맵
  • 와 " "의 비교File,Path , 「」InputStream

코드를 복사하면 신용카드를 주는 것을 잊지 마세요.

Stream MediaType.java

코드에서는-1인덱스의 는 건너뛰는 합니다.즉, '비교'는 '비교'를 의미합니다.-2는 파일 타입의 시그니처의 끝을 나타냅니다.이를 통해 바이너리 형식(주로 이미지)과 몇 가지 플레인텍스트 형식의 변형(HTML, SVG, XML)이 검출됩니다.코드는 데이터 소스 헤더에서 처음 11개의 "매직" 바이트를 사용합니다.논리를 단축하는 최적화와 개선은 환영할 만하다.

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.keenwrite.io.MediaType.*;
import static java.lang.System.arraycopy;

public class StreamMediaType {
  private static final int FORMAT_LENGTH = 11;
  private static final int END_OF_DATA = -2;

  private static final Map<int[], MediaType> FORMAT = new LinkedHashMap<>();

  static {
    //@formatter:off
    FORMAT.put( ints( 0x3C, 0x73, 0x76, 0x67, 0x20 ), IMAGE_SVG_XML );
    FORMAT.put( ints( 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ), IMAGE_PNG );
    FORMAT.put( ints( 0xFF, 0xD8, 0xFF, 0xE0 ), IMAGE_JPEG );
    FORMAT.put( ints( 0xFF, 0xD8, 0xFF, 0xEE ), IMAGE_JPEG );
    FORMAT.put( ints( 0xFF, 0xD8, 0xFF, 0xE1, -1, -1, 0x45, 0x78, 0x69, 0x66, 0x00 ), IMAGE_JPEG );
    FORMAT.put( ints( 0x49, 0x49, 0x2A, 0x00 ), IMAGE_TIFF );
    FORMAT.put( ints( 0x4D, 0x4D, 0x00, 0x2A ), IMAGE_TIFF );
    FORMAT.put( ints( 0x47, 0x49, 0x46, 0x38 ), IMAGE_GIF );
    FORMAT.put( ints( 0x8A, 0x4D, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ), VIDEO_MNG );
    FORMAT.put( ints( 0x25, 0x50, 0x44, 0x46, 0x2D, 0x31, 0x2E ), APP_PDF );
    FORMAT.put( ints( 0x38, 0x42, 0x50, 0x53, 0x00, 0x01 ), IMAGE_PHOTOSHOP );
    FORMAT.put( ints( 0x25, 0x21, 0x50, 0x53, 0x2D, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x2D ), APP_EPS );
    FORMAT.put( ints( 0x25, 0x21, 0x50, 0x53 ), APP_PS );
    FORMAT.put( ints( 0xFF, 0xFB, 0x30 ), AUDIO_MP3 );
    FORMAT.put( ints( 0x49, 0x44, 0x33 ), AUDIO_MP3 );
    FORMAT.put( ints( 0x3C, 0x21 ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x68, 0x74, 0x6D, 0x6C ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x68, 0x65, 0x61, 0x64 ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x62, 0x6F, 0x64, 0x79 ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x48, 0x54, 0x4D, 0x4C ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x48, 0x45, 0x41, 0x44 ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x42, 0x4F, 0x44, 0x59 ), TEXT_HTML );
    FORMAT.put( ints( 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20 ), TEXT_XML );
    FORMAT.put( ints( 0xFE, 0xFF, 0x00, 0x3C, 0x00, 0x3f, 0x00, 0x78 ), TEXT_XML );
    FORMAT.put( ints( 0xFF, 0xFE, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00 ), TEXT_XML );
    FORMAT.put( ints( 0x42, 0x4D ), IMAGE_BMP );
    FORMAT.put( ints( 0x23, 0x64, 0x65, 0x66 ), IMAGE_X_BITMAP );
    FORMAT.put( ints( 0x21, 0x20, 0x58, 0x50, 0x4D, 0x32 ), IMAGE_X_PIXMAP );
    FORMAT.put( ints( 0x2E, 0x73, 0x6E, 0x64 ), AUDIO_BASIC );
    FORMAT.put( ints( 0x64, 0x6E, 0x73, 0x2E ), AUDIO_BASIC );
    FORMAT.put( ints( 0x52, 0x49, 0x46, 0x46 ), AUDIO_WAV );
    FORMAT.put( ints( 0x50, 0x4B ), APP_ZIP );
    FORMAT.put( ints( 0x41, 0x43, -1, -1, -1, -1, 0x00, 0x00, 0x00, 0x00, 0x00 ), APP_ACAD );
    FORMAT.put( ints( 0xCA, 0xFE, 0xBA, 0xBE ), APP_JAVA );
    FORMAT.put( ints( 0xAC, 0xED ), APP_JAVA_OBJECT );
    //@formatter:on
  }

  private StreamMediaType() {
  }

  public static MediaType getMediaType( final Path path ) throws IOException {
    return getMediaType( path.toFile() );
  }

  public static MediaType getMediaType( final java.io.File file )
    throws IOException {
    try( final var fis = new FileInputStream( file ) ) {
      return getMediaType( fis );
    }
  }

  public static MediaType getMediaType( final InputStream is )
    throws IOException {
    final var input = new byte[ FORMAT_LENGTH ];
    final var count = is.read( input, 0, FORMAT_LENGTH );

    if( count > 1 ) {
      final var available = new byte[ count ];
      arraycopy( input, 0, available, 0, count );
      return getMediaType( available );
    }

    return UNDEFINED;
  }

  public static MediaType getMediaType( final byte[] data ) {
    assert data != null;

    final var source = new int[]{
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    for( int i = 0; i < data.length; i++ ) {
      source[ i ] = data[ i ] & 0xFF;
    }

    for( final var key : FORMAT.keySet() ) {
      int i = -1;
      boolean matches = true;

      while( ++i < FORMAT_LENGTH && key[ i ] != END_OF_DATA && matches ) {
        matches = key[ i ] == source[ i ] || key[ i ] == -1;
      }

      if( matches ) {
        return FORMAT.get( key );
      }
    }

    return UNDEFINED;
  }

  private static int[] ints( final int... data ) {
    final var magic = new int[ FORMAT_LENGTH ];
    int i = -1;
    while( ++i < data.length ) {
      magic[ i ] = data[ i ];
    }

    while( i < FORMAT_LENGTH ) {
      magic[ i++ ] = END_OF_DATA;
    }

    return magic;
  }
}

MediaType.java

IANA Media Type 목록에 따라 파일 형식을 정의합니다.파일명 확장자가 매핑되어 있는 것에 주의해 주세요.MediaTypeExtension의 Filename 는 Apache의 Filename Utils 에 getExtension★★★★★★ 。

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;

import static MediaType.TypeName.*;
import static MediaTypeExtension.getMediaType;
import static org.apache.commons.io.FilenameUtils.getExtension;

public enum MediaType {
  APP_ACAD( APPLICATION, "acad" ),
  APP_JAVA_OBJECT( APPLICATION, "x-java-serialized-object" ),
  APP_JAVA( APPLICATION, "java" ),
  APP_PS( APPLICATION, "postscript" ),
  APP_EPS( APPLICATION, "eps" ),
  APP_PDF( APPLICATION, "pdf" ),
  APP_ZIP( APPLICATION, "zip" ),
  FONT_OTF( "otf" ),
  FONT_TTF( "ttf" ),
  IMAGE_APNG( "apng" ),
  IMAGE_ACES( "aces" ),
  IMAGE_AVCI( "avci" ),
  IMAGE_AVCS( "avcs" ),
  IMAGE_BMP( "bmp" ),
  IMAGE_CGM( "cgm" ),
  IMAGE_DICOM_RLE( "dicom_rle" ),
  IMAGE_EMF( "emf" ),
  IMAGE_EXAMPLE( "example" ),
  IMAGE_FITS( "fits" ),
  IMAGE_G3FAX( "g3fax" ),
  IMAGE_GIF( "gif" ),
  IMAGE_HEIC( "heic" ),
  IMAGE_HEIF( "heif" ),
  IMAGE_HEJ2K( "hej2k" ),
  IMAGE_HSJ2( "hsj2" ),
  IMAGE_X_ICON( "x-icon" ),
  IMAGE_JLS( "jls" ),
  IMAGE_JP2( "jp2" ),
  IMAGE_JPEG( "jpeg" ),
  IMAGE_JPH( "jph" ),
  IMAGE_JPHC( "jphc" ),
  IMAGE_JPM( "jpm" ),
  IMAGE_JPX( "jpx" ),
  IMAGE_JXR( "jxr" ),
  IMAGE_JXRA( "jxrA" ),
  IMAGE_JXRS( "jxrS" ),
  IMAGE_JXS( "jxs" ),
  IMAGE_JXSC( "jxsc" ),
  IMAGE_JXSI( "jxsi" ),
  IMAGE_JXSS( "jxss" ),
  IMAGE_KTX( "ktx" ),
  IMAGE_KTX2( "ktx2" ),
  IMAGE_NAPLPS( "naplps" ),
  IMAGE_PNG( "png" ),
  IMAGE_PHOTOSHOP( "photoshop" ),
  IMAGE_SVG_XML( "svg+xml" ),
  IMAGE_T38( "t38" ),
  IMAGE_TIFF( "tiff" ),
  IMAGE_WEBP( "webp" ),
  IMAGE_WMF( "wmf" ),
  IMAGE_X_BITMAP( "x-xbitmap" ),
  IMAGE_X_PIXMAP( "x-xpixmap" ),
  AUDIO_BASIC( AUDIO, "basic" ),
  AUDIO_MP3( AUDIO, "mp3" ),
  AUDIO_WAV( AUDIO, "x-wav" ),
  VIDEO_MNG( VIDEO, "x-mng" ),
  TEXT_HTML( TEXT, "html" ),
  TEXT_MARKDOWN( TEXT, "markdown" ),
  TEXT_PLAIN( TEXT, "plain" ),
  TEXT_XHTML( TEXT, "xhtml+xml" ),
  TEXT_XML( TEXT, "xml" ),
  TEXT_YAML( TEXT, "yaml" ),

  /*
   * When all other lights go out.
   */
  UNDEFINED( TypeName.UNDEFINED, "undefined" );

  public enum TypeName {
    APPLICATION,
    AUDIO,
    IMAGE,
    TEXT,
    UNDEFINED,
    VIDEO
  }

  private final String mMediaType;
  private final TypeName mTypeName;
  private final String mSubtype;

  MediaType( final String subtype ) {
    this( IMAGE, subtype );
  }

  MediaType( final TypeName typeName, final String subtype ) {
    mTypeName = typeName;
    mSubtype = subtype;
    mMediaType = typeName.toString().toLowerCase() + '/' + subtype;
  }

  public static MediaType valueFrom( final File file ) {
    assert file != null;
    return fromFilename( file.getName() );
  }

  public static MediaType fromFilename( final String filename ) {
    assert filename != null;
    return getMediaType( getExtension( filename ) );
  }

  public static MediaType valueFrom( final Path path ) {
    assert path != null;
    return valueFrom( path.toFile() );
  }

  public static MediaType valueFrom( String contentType ) {
    if( contentType == null || contentType.isBlank() ) {
      return UNDEFINED;
    }

    var i = contentType.indexOf( ';' );
    contentType = contentType.substring(
      0, i == -1 ? contentType.length() : i );

    i = contentType.indexOf( '/' );
    i = i == -1 ? contentType.length() : i;
    final var type = contentType.substring( 0, i );
    final var subtype = contentType.substring( i + 1 );

    return valueFrom( type, subtype );
  }

  public static MediaType valueFrom(
    final String type, final String subtype ) {
    assert type != null;
    assert subtype != null;

    for( final var mediaType : values() ) {
      if( mediaType.equals( type, subtype ) ) {
        return mediaType;
      }
    }

    return UNDEFINED;
  }

  public boolean equals( final String type, final String subtype ) {
    assert type != null;
    assert subtype != null;

    return mTypeName.name().equalsIgnoreCase( type ) &&
      mSubtype.equalsIgnoreCase( subtype );
  }

  public boolean isType( final TypeName typeName ) {
    return mTypeName == typeName;
  }

  public String getSubtype() {
    return mSubtype;
  }
   
  @Override
  public String toString() {
    return mMediaType;
  }
}

MediaTypeExtension.java

은 ★★★★★★★★★★★★의 지도입니다.MediaType를 기존의 일반적인/일반적인 파일 이름 확장자로 지정합니다.이것에 의해, 파일명 확장자에 근거해 쌍방향 검색을 실시할 수 있습니다.

import static MediaType.*;
import static java.util.List.of;

public enum MediaTypeExtension {
  MEDIA_APP_ACAD( APP_ACAD, of( "dwg" ) ),
  MEDIA_APP_PDF( APP_PDF ),
  MEDIA_APP_PS( APP_PS, of( "ps" ) ),
  MEDIA_APP_EPS( APP_EPS ),
  MEDIA_APP_ZIP( APP_ZIP ),

  MEDIA_AUDIO_MP3( AUDIO_MP3 ),
  MEDIA_AUDIO_BASIC( AUDIO_BASIC, of( "au" ) ),
  MEDIA_AUDIO_WAV( AUDIO_WAV, of( "wav" ) ),

  MEDIA_FONT_OTF( FONT_OTF ),
  MEDIA_FONT_TTF( FONT_TTF ),

  MEDIA_IMAGE_APNG( IMAGE_APNG ),
  MEDIA_IMAGE_BMP( IMAGE_BMP ),
  MEDIA_IMAGE_GIF( IMAGE_GIF ),
  MEDIA_IMAGE_JPEG( IMAGE_JPEG,
                    of( "jpg", "jpe", "jpeg", "jfif", "pjpeg", "pjp" ) ),
  MEDIA_IMAGE_PNG( IMAGE_PNG ),
  MEDIA_IMAGE_PSD( IMAGE_PHOTOSHOP, of( "psd" ) ),
  MEDIA_IMAGE_SVG( IMAGE_SVG_XML, of( "svg" ) ),
  MEDIA_IMAGE_TIFF( IMAGE_TIFF, of( "tiff", "tif" ) ),
  MEDIA_IMAGE_WEBP( IMAGE_WEBP ),
  MEDIA_IMAGE_X_BITMAP( IMAGE_X_BITMAP, of( "xbm" ) ),
  MEDIA_IMAGE_X_PIXMAP( IMAGE_X_PIXMAP, of( "xpm" ) ),

  MEDIA_VIDEO_MNG( VIDEO_MNG, of( "mng" ) ),

  MEDIA_TEXT_MARKDOWN( TEXT_MARKDOWN, of(
    "md", "markdown", "mdown", "mdtxt", "mdtext", "mdwn", "mkd", "mkdown",
    "mkdn" ) ),
  MEDIA_TEXT_PLAIN( TEXT_PLAIN, of( "txt", "asc", "ascii", "text", "utxt" ) ),
  MEDIA_TEXT_R_MARKDOWN( TEXT_R_MARKDOWN, of( "Rmd" ) ),
  MEDIA_TEXT_R_XML( TEXT_R_XML, of( "Rxml" ) ),
  MEDIA_TEXT_XHTML( TEXT_XHTML, of( "xhtml" ) ),
  MEDIA_TEXT_XML( TEXT_XML ),
  MEDIA_TEXT_YAML( TEXT_YAML, of( "yaml", "yml" ) ),

  MEDIA_UNDEFINED( UNDEFINED, of( "undefined" ) );

  private final MediaType mMediaType;
  private final List<String> mExtensions;

  MediaTypeExtension( final MediaType mediaType ) {
    this( mediaType, of( mediaType.getSubtype() ) );
  }

  MediaTypeExtension(
    final MediaType mediaType, final List<String> extensions ) {
    assert mediaType != null;
    assert extensions != null;
    assert !extensions.isEmpty();

    mMediaType = mediaType;
    mExtensions = extensions;
  }

  public String getExtension() {
    return mExtensions.get( 0 );
  }

  public static MediaTypeExtension valueFrom( final MediaType mediaType ) {
    for( final var type : values() ) {
      if( type.isMediaType( mediaType ) ) {
        return type;
      }
    }

    return MEDIA_UNDEFINED;
  }

  boolean isMediaType( final MediaType mediaType ) {
    return mMediaType == mediaType;
  }

  static MediaType getMediaType( final String extension ) {
    final var sanitized = sanitize( extension );

    for( final var mediaType : MediaTypeExtension.values() ) {
      if( mediaType.isType( sanitized ) ) {
        return mediaType.getMediaType();
      }
    }

    return UNDEFINED;
  }

  private boolean isType( final String sanitized ) {
    for( final var extension : mExtensions ) {
      if( extension.equalsIgnoreCase( sanitized ) ) {
        return true;
      }
    }

    return false;
  }

  private static String sanitize( final String extension ) {
    return extension == null ? "" : extension.toLowerCase();
  }

  private MediaType getMediaType() {
    return mMediaType;
  }
}

사용방법:

// EXAMPLE -- Detect media type
//
final File image = new File( "filename.jpg" );
final MediaType mt = StreamMediaType.getMediaType( image );

// Tricky! The JPG could be a PNG in disguise.
if( mt.isType( MediaType.TypeName.IMAGE ) ) {

  if( mt == MediaType.IMAGE_PNG ) {
    // Nice try! Sneaky sneak.
  }
}

// EXAMPLE -- Get typical media type file name extension
//
final String ext = MediaTypeExtension.valueFrom( MediaType.IMAGE_SVG_XML ).getExtension();

// EXAMPLE -- Get media type from HTTP request
//
final var url = new URL( "https://localhost/path/file.ext" );
final var conn = (HttpURLConnection) url.openConnection();
final var contentType = conn.getContentType();
MediaType mediaType = valueFrom( contentType );

// Fall back to stream detection probe
if( mediaType == UNDEFINED ) {
  mediaType = StreamMediaType.getMediaType( conn.getInputStream() );
}

conn.disconnect();

무슨 말인지 아시겠죠?


간단한 라이브러리 리뷰:

  • Apache Tika - 600kb Bloat. 설정할 행이 여러 개 필요하고 JAR 파일이 여러 개 필요합니다.
  • jMimeMagic - 미완료.설정하려면 여러 행이 필요합니다.
  • MimeUtil2 - 크기가 상당히 커서 즉시 사용할 수 없습니다.
  • FileTypeDetector - JDK와 번들되어 있으며, 숲에 서식하는 소나무 딱정벌레보다 더 버그가 많습니다.
  • Files.probe 내용유형 - 탐지 기능은 플랫폼에 따라 다르며 신뢰할 수 없는 으로 간주됩니다(원본).
  • Mimetypes FileTypeMap - activation.jar와 함께 번들되며 파일 이름 확장자를 사용합니다.

테스트용 오디오, 비디오 및 이미지 파일의 예:


1 "MIME type"은 사용되지 않는 용어입니다.

Linux OS가 .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'

다른 여러 도서관들을 둘러본 후 나는 마임유틸리티로 결정했다.

<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;
}
File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();

나는 다음과 같은 코드로 그것을 했다.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MimeFileType {

    public static void main(String args[]){

        try{
            URL url = new URL ("https://www.url.com.pdf");

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            InputStream content = (InputStream)connection.getInputStream();
            connection.getHeaderField("Content-Type");

            System.out.println("Content-Type "+ connection.getHeaderField("Content-Type"));

            BufferedReader in = new BufferedReader (new InputStreamReader(content));

        }catch (Exception e){

        }
    }
}

스트림 또는 파일의 매직바이트를 확인합니다.

https://stackoverflow.com/a/65667558/3225638

Java를를 정의해야 .enum검출할 타입을 지정합니다.

파일 확장자를 MIME 유형에 매핑하는 신뢰할 수 있는(즉, 일관된) 방법을 원하는 경우 다음과 같이 사용합니다.

https://github.com/jjYBdx4IL/misc/blob/master/text-utils/src/main/java/com/github/jjYBdx4IL/utils/text/MimeType.java

번들된 MIME 타입 데이터베이스를 포함하고 기본적으로 데이터베이스를 사용하여 "programmatic" 엔트리를 초기화함으로써 javax.activation의 MimetypeFileTypeMap 클래스의 논리를 반전시킵니다.이렇게 하면 라이브러리 정의 유형은 항상 번들되지 않은 리소스에서 정의될 수 있는 것보다 우선합니다.

언급URL : https://stackoverflow.com/questions/51438/how-to-get-a-files-media-type-mime-type

반응형