때로는 Jeb와 Jens의 답변이 작동하지 않고 null을 반환합니다. 이 경우 다음 해결책을 사용합니다. 파일 헤드는 일반적으로 형식 서명을 포함합니다. 나는 그것을 읽고 서명 목록에 알려진 것과 비교 합니다 .
/**
*
* @param is InputStream on start of file. Otherwise signature can not be defined.
* @return int id of signature or -1, if unknown signature was found. See SIGNATURE_ID_(type) constants to
* identify signature by its id.
* @throws IOException in cases of read errors.
*/
public static int getSignatureIdFromHeader(InputStream is) throws IOException {
// read signature from head of source and compare with known signatures
int signatureId = -1;
int sigCount = SIGNATURES.length;
int[] byteArray = new int[MAX_SIGNATURE_LENGTH];
StringBuilder builder = new StringBuilder();
for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
byteArray[i] = is.read();
builder.append(Integer.toHexString(byteArray[i]));
}
if (DEBUG) {
Log.d(TAG, "head bytes=" + builder.toString());
}
for (int i = 0; i < MAX_SIGNATURE_LENGTH; i++) {
// check each bytes with known signatures
int bytes = byteArray[i];
int lastSigId = -1;
int coincidences = 0;
for (int j = 0; j < sigCount; j++) {
int[] sig = SIGNATURES[j];
if (DEBUG) {
Log.d(TAG, "compare" + i + ": " + Integer.toHexString(bytes) + " with " + sig[i]);
}
if (bytes == sig[i]) {
lastSigId = j;
coincidences++;
}
}
// signature is unknown
if (coincidences == 0) {
break;
}
// if first bytes of signature is known we check signature for full coincidence
if (coincidences == 1) {
int[] sig = SIGNATURES[lastSigId];
int sigLength = sig.length;
boolean isSigKnown = true;
for (; i < MAX_SIGNATURE_LENGTH && i < sigLength; i++) {
bytes = byteArray[i];
if (bytes != sig[i]) {
isSigKnown = false;
break;
}
}
if (isSigKnown) {
signatureId = lastSigId;
}
break;
}
}
return signatureId;
}
signatureId
서명 배열의 서명 색인입니다. 예를 들어
private static final int[] SIGNATURE_PNG = hexStringToIntArray("89504E470D0A1A0A");
private static final int[] SIGNATURE_JPEG = hexStringToIntArray("FFD8FF");
private static final int[] SIGNATURE_GIF = hexStringToIntArray("474946");
public static final int SIGNATURE_ID_JPEG = 0;
public static final int SIGNATURE_ID_PNG = 1;
public static final int SIGNATURE_ID_GIF = 2;
private static final int[][] SIGNATURES = new int[3][];
static {
SIGNATURES[SIGNATURE_ID_JPEG] = SIGNATURE_JPEG;
SIGNATURES[SIGNATURE_ID_PNG] = SIGNATURE_PNG;
SIGNATURES[SIGNATURE_ID_GIF] = SIGNATURE_GIF;
}
이제 파일의 URI가 없어도 파일 형식이 있습니다. 다음으로 파일 유형별로 MIME 유형을 얻습니다. 얻을 수있는 MIME 유형을 모르는 경우이 표 에서 적절한 것을 찾을 수 있습니다 .
많은 파일 형식에서 작동합니다. 그러나 비디오의 경우 MIME 유형을 얻으려면 비디오 코덱을 알아야하므로 작동하지 않습니다. 비디오의 MIME 유형을 얻으려면 MediaMetadataRetriever를 사용 합니다.