我有来自 api 的文档的 base64 字符串。我想知道那是什么扩展名/文件格式。因为如果它是 jpg/jpeg/png 我想在图像小部件中显示它。或者,如果它是 pdf 格式,我想在 PdfView 小部件中显示它。那么有没有办法从base64获取文件扩展名。有包吗
如果您有 Base64 字符串,您可以通过检查 Base64 字符串的第一个字符来检测文件类型:
'/' 表示 jpeg。
“i”表示 png。
“R”表示 gif。
“U”表示 webp。
“J”表示 PDF。
我为此编写了一个函数:
String getBase64FileExtension(String base64String) {
switch (base64String.characters.first) {
case '/':
return 'jpeg';
case 'i':
return 'png';
case 'R':
return 'gif';
case 'U':
return 'webp';
case 'J':
return 'pdf';
default:
return 'unknown';
}
}
如果您没有原始文件名,则无法恢复它。 这些元数据不属于文件内容,并且 base64 编码仅对文件内容进行操作。 最好能保存原来的文件名。
package:mime
从少量二进制数据中猜测文件的MIME类型。 您可以解码 Base64 字符串中的前 n×4 个字符(有效的 Base64 字符串的长度必须是 4 的倍数),对其进行解码,然后调用 lookupMimeType
。
package:mime
有一个 defaultMagicNumbersMaxLength
值,可用于动态计算 n:
import 'dart:convert';
import 'package:mime/mime.dart' as mime;
String? guessMimeTypeFromBase64(String base64String) {
// Compute the minimum length of the base64 string we need to decode
// [mime.defaultMagicNumbersMaxLength] bytes. base64 encodes 3 bytes of
// binary data to 4 characters.
var minimumBase64Length = (mime.defaultMagicNumbersMaxLength / 3).ceil() * 4;
return mime.lookupMimeType(
'',
headerBytes: base64.decode(base64String.substring(0, minimumBase64Length)),
);
}
对于
package:mime
在编写时支持的类型,mime.defaultMagicNumbersMaxLength
为 12(这意味着需要解码 Base64 字符串的前 16 个字节)。
一种解决方案是使用 Magic Numbers 从 Base64 检测文件类型:
import 'dart:convert';
import 'dart:typed_data';
String getFileExtensionFromBase64(String base64String) {
// Decode base64 to get the raw bytes
Uint8List bytes = base64Decode(base64String);
// Check the magic numbers to determine the file type
if (bytes.startsWith([0xFF, 0xD8])) {
return 'jpg'; // JPEG file
} else if (bytes.startsWith([0x89, 0x50, 0x4E, 0x47])) {
return 'png'; // PNG file
} else if (bytes.startsWith([0x25, 0x50, 0x44, 0x46])) {
return 'pdf'; // PDF file
} else if (bytes.startsWith([0x00, 0x00, 0x00, 0x18]) || bytes.startsWith([0x00, 0x00, 0x00, 0x20])) {
return 'mp4'; // MP4 video
} else if (bytes.startsWith([0x1A, 0x45, 0xDF, 0xA3])) {
return 'mkv'; // MKV video
} else if (bytes.startsWith([0x49, 0x44, 0x33])) {
return 'mp3'; // MP3 audio
} else if (bytes.startsWith([0x4F, 0x67, 0x67, 0x53])) {
return 'ogg'; // OGG audio
} else {
return 'unknown'; // Could not identify the file
}
}
// Helper function to check if the bytes start with a specific sequence
extension Uint8ListExtensions on Uint8List {
bool startsWith(List<int> pattern) {
if (pattern.length > this.length) return false;
for (int i = 0; i < pattern.length; i++) {
if (this[i] != pattern[i]) return false;
}
return true;
}
}