Improve file type detecting

This commit is contained in:
Him188 2021-01-05 20:35:10 +08:00
parent f6faf19ad8
commit d5cdd9e161
2 changed files with 16 additions and 7 deletions

View File

@ -61,9 +61,10 @@ public interface ExternalResource : Closeable {
* 文件格式 "png", "amr". 当无法自动识别格式时为 [DEFAULT_FORMAT_NAME]. * 文件格式 "png", "amr". 当无法自动识别格式时为 [DEFAULT_FORMAT_NAME].
* *
* 默认会从文件头识别, 支持的文件类型: * 默认会从文件头识别, 支持的文件类型:
* png, jpg, gif, tif, bmp, wav, amr, silk * png, jpg, gif, tif, bmp, amr, silk
* *
* @see net.mamoe.mirai.utils.getFileType * @see net.mamoe.mirai.utils.getFileType
* @see net.mamoe.mirai.utils.FILE_TYPES
* @see DEFAULT_FORMAT_NAME * @see DEFAULT_FORMAT_NAME
*/ */
public val formatName: String public val formatName: String
@ -88,7 +89,7 @@ public interface ExternalResource : Closeable {
public companion object { public companion object {
/** /**
* 在无法识别文件格式时使用的默认格式名. * 在无法识别文件格式时使用的默认格式名. "mirai".
* *
* @see ExternalResource.formatName * @see ExternalResource.formatName
*/ */
@ -265,7 +266,7 @@ public interface ExternalResource : Closeable {
private fun InputStream.detectFileTypeAndClose(): String? { private fun InputStream.detectFileTypeAndClose(): String? {
val buffer = ByteArray(10) val buffer = ByteArray(COUNT_BYTES_USED_FOR_DETECTING_FILE_TYPE)
return use { return use {
kotlin.runCatching { it.read(buffer) }.onFailure { return null } kotlin.runCatching { it.read(buffer) }.onFailure { return null }
getFileType(buffer) getFileType(buffer)
@ -320,7 +321,7 @@ internal class ExternalResourceImplByByteArray(
override val size: Long = data.size.toLong() override val size: Long = data.size.toLong()
override val md5: ByteArray by lazy { data.md5() } override val md5: ByteArray by lazy { data.md5() }
override val formatName: String by lazy { override val formatName: String by lazy {
formatName ?: getFileType(data.copyOf(8)).orEmpty() formatName ?: getFileType(data.copyOf(COUNT_BYTES_USED_FOR_DETECTING_FILE_TYPE)).orEmpty()
} }
override fun inputStream(): InputStream = data.inputStream() override fun inputStream(): InputStream = data.inputStream()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2019-2020 Mamoe Technologies and contributors. * Copyright 2019-2021 Mamoe Technologies and contributors.
* *
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -21,13 +21,18 @@ public val FILE_TYPES: MutableMap<String, String> = mutableMapOf(
"47494638" to "gif", "47494638" to "gif",
"49492A00" to "tif", "49492A00" to "tif",
"424D" to "bmp", "424D" to "bmp",
"57415645" to "wav",
// "57415645" to "wav", // server doesn't support
"2321414D52" to "amr", "2321414D52" to "amr",
"02232153494C4B5F5633" to "silk", "02232153494C4B5F5633" to "silk",
) )
/**
* [getFileType] 需要的 [ByteArray] 长度
*/
public val COUNT_BYTES_USED_FOR_DETECTING_FILE_TYPE: Int get() = FILE_TYPES.maxOf { it.key.length / 2 }
/* /*
startsWith("FFD8") -> "jpg" startsWith("FFD8") -> "jpg"
@ -40,7 +45,10 @@ public val FILE_TYPES: MutableMap<String, String> = mutableMapOf(
* 根据文件头获取文件类型 * 根据文件头获取文件类型
*/ */
public fun getFileType(fileHeader: ByteArray): String? { public fun getFileType(fileHeader: ByteArray): String? {
val hex = fileHeader.toUHexString("") val hex = fileHeader.toUHexString(
"",
length = COUNT_BYTES_USED_FOR_DETECTING_FILE_TYPE.coerceAtMost(fileHeader.size)
)
FILE_TYPES.forEach { (k, v) -> FILE_TYPES.forEach { (k, v) ->
if (hex.startsWith(k)) { if (hex.startsWith(k)) {
return v return v