java Android -从无扩展名的文件获取MIME类型

gg58donl  于 2023-02-02  发布在  Java
关注(0)|答案(4)|浏览(190)

据我所知,只有三种方法可以通过阅读现有问题来获取MIME类型。
1)使用MimeTypeMap.getFileExtensionFromUrl从文件扩展名确定它
2)使用inputStreamURLConnection.guessContentTypeFromStream进行“猜测”
3)使用ContentResolver获取MIME类型,使用内容Uri(content:\)context.getContentResolver().getType
但是我只有file对象,可以得到的Uri是文件路径Uri(file:),文件没有扩展名,还有什么办法可以得到文件的MIME类型,或者从文件路径Uri判断内容Uri?

tpgth1q7

tpgth1q71#

你试过这个吗?它对我有效(只适用于图像文件)。

public static String getMimeTypeOfUri(Context context, Uri uri) {
    BitmapFactory.Options opt = new BitmapFactory.Options();
    /* The doc says that if inJustDecodeBounds set to true, the decoder
     * will return null (no bitmap), but the out... fields will still be
     * set, allowing the caller to query the bitmap without having to
     * allocate the memory for its pixels. */
    opt.inJustDecodeBounds = true;

    InputStream istream = context.getContentResolver().openInputStream(uri);
    BitmapFactory.decodeStream(istream, null, opt);
    istream.close();

    return opt.outMimeType;
}

当然你也可以使用其他的方法,比如BitmapFactory.decodeFile或者BitmapFactory.decodeResource,如下所示:

public static String getMimeTypeOfFile(String pathName) {
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(pathName, opt);
    return opt.outMimeType;
}

如果无法确定MIME类型,它将返回null。

0tdrvxhp

0tdrvxhp2#

是否还有一种方法可以获取文件的MIME类型?
不仅仅是文件名。
或者一种从文件路径Uri确定内容Uri的方法?
不一定有任何“内容URI”。欢迎您尝试在MediaStore中查找该文件,并查看是否由于某种原因,它碰巧知道MIME类型。MediaStore可能知道也可能不知道MIME类型,如果它不知道,则无法确定它。
如果您 * 确实 * 有content://Uri,请在ContentResolver上使用getType()来获取MIME类型。

57hvy0tb

57hvy0tb3#

第一个字节包含文件扩展名

@Nullable
public static String getFileExtFromBytes(File f) {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(f);
        byte[] buf = new byte[5]; //max ext size + 1
        fis.read(buf, 0, buf.length);
        StringBuilder builder = new StringBuilder(buf.length);
        for (int i=1;i<buf.length && buf[i] != '\r' && buf[i] != '\n';i++) {
            builder.append((char)buf[i]);
        }
        return builder.toString().toLowerCase();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return null;
}
mwkjh3gx

mwkjh3gx4#

要获取没有扩展名的文件的MIME类型,您需要使用不同的方法。一种方法是读取文件的前几个字节,并根据文件格式签名(也称为“幻数”)确定MIME类型。

import java.io.FileInputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder

fun getMimeTypeWithoutExtension(filePath: String): String {
val magicNumbers = mapOf(
    0x89.toByte() to "image/png",
    0xff.toByte() to "image/jpeg",
    0x47.toByte() to "image/gif",
    0x49.toByte() to "image/tiff",
    0x4d.toByte() to "image/tiff",
    0x25.toByte() to "application/pdf",
    0x50.toByte() to "application/vnd.ms-powerpoint",
    0xD0.toByte() to "application/vnd.ms-word",
    0x43.toByte() to "application/vnd.ms-word",
    0x53.toByte() to "application/vnd.ms-word"
)

var mimeType = "application/octet-stream"
FileInputStream(filePath).use { inputStream ->
    val buffer = ByteArray(1024)
    inputStream.read(buffer, 0, buffer.size)
    val magicNumber = ByteBuffer.wrap(buffer).order(ByteOrder.BIG_ENDIAN).get().toInt() and 0xff
    mimeType = magicNumbers[magicNumber.toByte()] ?: mimeType
}
return mimeType
}

此代码使用FileInputStream类将文件的第一个字节读入ByteArray。然后将该字节提取为整数,并用于在幻数和MIME类型的Map中查找相应的MIME类型。如果无法确定MIME类型,则函数将返回“application/octet-stream”作为默认值。
请注意,此代码仅检查文件的第一个字节,因此它可能无法始终准确地确定不带扩展名的文件的MIME类型。要获得更准确的结果,您可能需要检查文件的其他字节或使用提供更全面MIME类型检测的库。

相关问题