NAME

Module::Generic::File::Magic - File type and MIME detection with 3-level backend cascade

SYNOPSIS

use Module::Generic::File::Magic qw( :flags );

my $magic = Module::Generic::File::Magic->new( flags => MAGIC_MIME_TYPE ) ||
    die( Module::Generic::File::Magic->error );

# Which backend is active?
printf "Backend: %s\n", $magic->backend;    # xs, json, or file

# Detect from a file path
my $mime = $magic->from_file( '/path/to/archive.tar.gz' ) ||
    die( $magic->error );
# -> "application/gzip"

# Detect from an in-memory buffer
open( my $fh, '<:raw', '/path/to/file' ) or die( $! );
read( $fh, my $buf, 4096 );
close( $fh );
my $mime = $magic->from_buffer( $buf ) || die( $magic->error );

# Detect from an open filehandle
open( my $fh, '<:raw', '/path/to/file' ) or die( $! );
my $mime = $magic->from_filehandle( $fh ) || die( $magic->error );

# Convenience wrappers
my $type = $magic->mime_type_from_file( '/path/to/file' );
my $enc  = $magic->mime_encoding_from_file( '/path/to/file' );
my $full = $magic->mime_from_file( '/path/to/file' );
# -> "application/gzip; charset=binary"

# Control the read size for pure-Perl backends (default: 512 bytes)
my $magic2 = Module::Generic::File::Magic->new(
    flags    => MAGIC_MIME_TYPE,
    max_read => 1024,
) || die( Module::Generic::File::Magic->error );

# Change max_read at any time
$magic->max_read(1024);

# Procedural interface
use Module::Generic::File::Magic qw( :functions );
my $mime = magic_mime_type( '/path/to/file' );

VERSION

v0.1.1

DESCRIPTION

Module::Generic::File::Magic detects file types and MIME types using a three-level cascade, automatically selecting the best available backend:

Level 1 - xs (preferred)

libmagic.so.1 is loaded at runtime via dlopen(3) - no magic.h, no libmagic-dev package required at build time. Full libmagic accuracy and performance. The MAGIC_COMPRESS, MAGIC_SYMLINK, and all other flags are fully supported. compile(), check(), and list() are only available at this level.

Level 2 - json

libmagic is absent. The module loads lib/Module/Generic/File/magic.json (generated from the freedesktop.org shared-mime-info database, bundled with the distribution) and runs pure-Perl byte-pattern matching. Covers ~500 MIME types with magic signatures.

Level 3 - file

No pattern matched at level 2. Invokes file(1) in a subprocess as a last resort. from_buffer writes a temporary file via File::Temp.

The active backend is available via $magic->backend and the package variable $Module::Generic::File::Magic::BACKEND.

Note that within the json backend, a text-content heuristic is applied before falling through to file(1).

CONSTRUCTOR

new

my $magic = Module::Generic::File::Magic->new( %opts ) ||
    die( Module::Generic::File::Magic->error );
  • flags - integer bitmask (default: MAGIC_NONE)

  • magic_db - path to a custom .mgc database (xs backend only)

  • max_read - maximum bytes read from a file for pure-Perl backends (default: 512)

METHODS

backend

Returns the name of the active backend: "xs", "json", or "file". Note that the reported value is the top-level configured backend; the actual detection at runtime may cascade through multiple levels.

check( [ $filename ] )

Validates a magic database. xs backend only.

close

Releases the magic_t cookie. No-op on non-xs backends.

compile( $filename )

Compiles a magic source file into a .mgc database. xs backend only.

flags

Getter/setter for the libmagic flags bitmask.

from_buffer( $scalar )

Detects type from a raw byte scalar.

from_file( $path )

Detects type from a file path.

from_filehandle( $fh )

Detects type from an open filehandle.

list( [ $filename ] )

Prints magic database entries to stdout. xs backend only.

magic_db

Getter/setter for the custom magic database path (xs backend only).

max_read( [ $bytes ] )

Getter/setter for the maximum number of bytes read from a file when using pure-Perl backends. The default is 512 bytes, which covers all signatures in the bundled JSON database. Increase this value for formats whose signatures appear at large offsets (e.g. application/x-tar at offset 257).

mime_encoding_from_buffer( $scalar )

Returns the charset (e.g. binary) for the given buffer.

mime_encoding_from_file( $path )

Returns the charset (e.g. us-ascii) for the given file.

mime_encoding_from_filehandle( $fh )

Returns the charset for the given filehandle.

mime_from_buffer( $scalar )

Returns the full MIME string (e.g. application/gzip; charset=binary) for the given buffer.

mime_from_file( $path )

Returns the full MIME string for the given file.

mime_from_filehandle( $fh )

Returns the full MIME string for the given filehandle.

mime_type_from_buffer( $scalar )

Returns the MIME type (e.g. application/gzip) for the given buffer.

mime_type_from_file( $path )

Returns the MIME type for the given file.

mime_type_from_filehandle( $fh )

Returns the MIME type for the given filehandle.

version

Returns the libmagic version string (e.g. "5.45"), or undef when not using the xs backend.

EXPORTED FUNCTIONS

use Module::Generic::File::Magic qw( :functions );
magic_from_buffer( $scalar [, $flags] )
magic_from_file( $path [, $flags] )
magic_mime_type( $path )
magic_mime_encoding( $path )

magic_from_buffer( $scalar [, $flags] )

Procedural interface to "from_buffer". $flags defaults to MAGIC_MIME_TYPE.

magic_from_file( $path [, $flags] )

Procedural interface to "from_file". $flags defaults to MAGIC_MIME_TYPE.

magic_mime_type( $path )

Returns the MIME type of $path. Equivalent to magic_from_file( $path, MAGIC_MIME_TYPE ).

magic_mime_encoding( $path )

Returns the charset of $path. Equivalent to magic_from_file( $path, MAGIC_MIME_ENCODING ).

EXPORT TAGS

:flags, :functions, :all

FLAG CONSTANTS

MAGIC_NONE

No flags (default)

MAGIC_DEBUG

Print debug messages to stderr [xs only]

Follow symlinks

MAGIC_COMPRESS

Examine inside compressed files

MAGIC_DEVICES

Look at block/char device content [xs only]

MAGIC_MIME_TYPE

Return MIME type

MAGIC_MIME_ENCODING

Return MIME charset

MAGIC_MIME

MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING

MAGIC_CONTINUE

Return all matches [xs only]

MAGIC_CHECK

Print warnings [xs only]

MAGIC_PRESERVE_ATIME

Restore access time [xs only]

MAGIC_RAW

Do not convert unprintable chars [xs only]

MAGIC_ERROR

Treat ENOENT as real error [xs only]

MAGIC_APPLE

Return Apple creator/type [xs only]

MAGIC_EXTENSION

Return file extensions [xs only]

MAGIC_COMPRESS_TRANSP

Do not report on the compression type, only the uncompressed content. [xs only]

MAGIC_NO_CHECK_COMPRESS

Disable compression check. [xs only]

MAGIC_NO_CHECK_TAR

Disable tar check. [xs only]

MAGIC_NO_CHECK_SOFT

Disable soft magic check. [xs only]

MAGIC_NO_CHECK_APPTYPE

Disable Apple creator/type check. [xs only]

MAGIC_NO_CHECK_ELF

Disable ELF check. [xs only]

MAGIC_NO_CHECK_TEXT

Disable text check. [xs only]

MAGIC_NO_CHECK_CDF

Disable CDF check. [xs only]

MAGIC_NO_CHECK_TOKENS

Disable token check. [xs only]

MAGIC_NO_CHECK_ENCODING

Disable encoding check. [xs only]

Flags marked [xs only] are silently ignored on non-xs backends.

Flags marked [xs only] are silently ignored on non-xs backends.

INSTALLATION

The only requirement for the xs backend is the libmagic1 runtime package:

# Debian / Ubuntu
sudo apt-get install libmagic1

# RPM-based
sudo yum install file-libs

# macOS (Homebrew)
brew install libmagic

No libmagic-dev or file-devel required. The module compiles and works on any system with a C compiler (the same one that built Perl).

FILES

  • lib/Module/Generic/File/magic.json

    Bundled magic signature database generated from the freedesktop.org shared-mime-info XML. Used by the json backend. To regenerate:

    perl scripts/gen_magic_json.pl [xml_path] [out_json_path]

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

Module::Generic::Finfo, File::LibMagic, File::MimeInfo

The libmagic(3) man page.

COPYRIGHT & LICENSE

Copyright (c) 2026 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.