Skip to content

A Flutter package to detect file types based on their magic number instead of MIME types. Supports Flutter on mobile, desktop, and web without native code.

License

Notifications You must be signed in to change notification settings

vicajilau/file_magic_number

Repository files navigation

File Magic Number Logo

File Magic Number

Pub Version CI Status CD Status Code Coverage

A Flutter package to detect file types based on their magic number instead of relying on MIME types. Works on Flutter for mobile, desktop, and web without requiring native code.

🚀 Features

  • Detects file types using their magic number (signature bytes)
  • Supports Flutter on Android, iOS, macOS, Windows, Linux, and Web
  • No need for native plugins
  • Lightweight and easy to extend with custom signatures

📌 Installation

Add the dependency to your pubspec.yaml:

dependencies:
  file_magic_number: latest_version

Then for Flutter, run:

flutter pub get

🛠️ Usage

Detect a file type from bytes

We can synchronously detect the file type using the bytes of the file.

import 'package:file_magic_number/file_magic_number.dart';

void main() {
  final bytes = Uint8List.fromList([0x25, 0x50, 0x44, 0x46]);
  final FileMagicNumberType fileType = FileMagicNumber.detectFileTypeFromBytes(bytes);
  print(fileType);
}

Detect a file type from path or blob

We can asynchronously detect the file type using the path or blob of the file.
This requires that for Android, iOS, Linux, MacOS, and Windows, we pass the file path.
In the web version, this parameter must be the blob of the file.

Note: This method may throw a PathNotFoundException if the file is not found.
It is recommended to handle this exception appropriately as shown in the following example.

import 'package:file_magic_number/file_magic_number.dart';

void main() async {
  final pathOrBlob = "my_path_or_blob";
  try {
    final FileMagicNumberType fileType = await FileMagicNumber.detectFileTypeFromPathOrBlob(pathOrBlob);
    print(fileType);
  } catch (e) {
    print("The file was not found.");
  }
}

Detect a file type from file_picker

Integrating file_magic_number with file_picker allows you to easily detect the type of a file selected by the user without relying on MIME types.

Using bytes

You can use file_picker to open the file dialog and then pass the file's bytes to FileMagicNumber.detectFileTypeFromBytes to identify its type. Here's how you can do it:

import 'package:file_magic_number/file_magic_number.dart';
import 'package:file_picker/file_picker.dart';

void main() async {
  FilePickerResult? result = await FilePicker.platform.pickFiles(withData: true);

  if (result != null) {
    final FileMagicNumberType fileType = FileMagicNumber.detectFileTypeFromBytes(result.files.single.bytes);
    print(fileType);
  }
}

Using pathOrBlob

You can use file_picker to open the file dialog and then pass the file's path or blob to FileMagicNumber.detectFileTypeFromBytes to identify its type. Here's how you can do it:

Note: This method may throw a PathNotFoundException if the file is not found.
It is recommended to handle this exception appropriately as shown in the following example.

import 'package:file_magic_number/file_magic_number.dart';
import 'package:file_picker/file_picker.dart';

void main() async {
  FilePickerResult? result = await FilePicker.platform.pickFiles();

  if (result != null && result.files.single.path != null) {
    try {
      final FileMagicNumberType fileType = await FileMagicNumber.detectFileTypeFromPathOrBlob(result.files.single.path!);
      print(fileType);
    } catch (e) {
      print("The file was not found.");
    }
  }
}

🎯 Supported File Types

File Type Magic Number (Hex)
ZIP 50 4B 03 04
RAR 52 61 72 21 1A 07 00
RAR 52 61 72 21 1A 07
7Z 37 7A BC AF 27 1C
PDF 25 50 44 46
PNG 89 50 4E 47 0D 0A 1A 0A
JPG FF D8 FF
GIF 47 49 46 38
TIFF 49 49 2A 00 / 4D 4D 00 2A
BMP 42 4D
MP3 49 44 33
WAV 52 49 46 46
MP4 66 74 79 70
ELF 7F 45 4C 46
EXE 4D 5A
TAR 75 73 74 61 72
SQLite 53 51 4C 69 74 65

📌 Contributing

Feel free to contribute by adding more file signatures or improving the implementation. Fork the repo and submit a PR!

📜 License

This project is licensed under the MIT License.