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, 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.FILE_TYPES
* @see DEFAULT_FORMAT_NAME
*/
public val formatName: String
@ -88,7 +89,7 @@ public interface ExternalResource : Closeable {
public companion object {
/**
* 在无法识别文件格式时使用的默认格式名.
* 在无法识别文件格式时使用的默认格式名. "mirai".
*
* @see ExternalResource.formatName
*/
@ -265,7 +266,7 @@ public interface ExternalResource : Closeable {
private fun InputStream.detectFileTypeAndClose(): String? {
val buffer = ByteArray(10)
val buffer = ByteArray(COUNT_BYTES_USED_FOR_DETECTING_FILE_TYPE)
return use {
kotlin.runCatching { it.read(buffer) }.onFailure { return null }
getFileType(buffer)
@ -320,7 +321,7 @@ internal class ExternalResourceImplByByteArray(
override val size: Long = data.size.toLong()
override val md5: ByteArray by lazy { data.md5() }
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()

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 许可证的约束, 可以在以下链接找到该许可证.
* 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",
"49492A00" to "tif",
"424D" to "bmp",
"57415645" to "wav",
// "57415645" to "wav", // server doesn't support
"2321414D52" to "amr",
"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"
@ -40,7 +45,10 @@ public val FILE_TYPES: MutableMap<String, String> = mutableMapOf(
* 根据文件头获取文件类型
*/
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) ->
if (hex.startsWith(k)) {
return v