Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

file command replacement (showing the type of a file with perl)

by pvaldes (Chaplain)
on Apr 17, 2012 at 12:13 UTC ( #965499=perlquestion: print w/ replies, xml ) Need Help??
pvaldes has asked for the wisdom of the Perl Monks concerning the following question:

As everybody surely knows, the "file" command in bash prints info about the type of a file. (i.e file flower.jpg will show that this is a jpeg image)

I'm trying to achieve the same in a perl script. Thus I wrote something like this:

use strict; use File::Type; my $infile = "flower.jpg"; my $ft = File::Type->new(); my $type1 = $ft->checktype_filename($infile); my $type2 = $ft->mime_type($infile); print "$type1\n"; print "$type2\n"; print `file $infile`;

and my proto-script returns

image/jpeg image/jpeg flower.jpg: JPEG image data, JFIF standard 1.01

Thus we have a clear winner, the File::Type module, although not bad, is clearly less accurate that file. And that's the question: żDo you know any way/module/function integrated with perl to obtain the same amount of info about a file? or I need to use system here to call directly the file command?. The big nuisance here is that if you search for file + perl in google you obtain millions of unrelated results

Comment on file command replacement (showing the type of a file with perl)
Select or Download Code
Re: file command replacement (showing the type of a file with perl)
by halfcountplus (Hermit) on Apr 17, 2012 at 12:41 UTC

    the File::Type module, although not bad, is clearly less accurate that file.

    You've misunderstood something. The explicit purpose of File::Type is "to determine the MIME type of that file".

    'image/jpeg' is a valid MIME type. 'JPEG image data, JFIF standard 1.01' is not. MIME types are important, eg, in internet transfers -- your browser decides how to treat something based on the MIME type in the http header.

    The file command (which will give you a mime type too, if you use the --mime switch) can provide more detailed information in a "human readable" form but there is no protocol for this. It looks to me like someone has written a module porting "file" into perl tho: file.

    However, since the author admits "this implementation is significantly slower than the C version" you might be better off just using backticks ;).

Re: file command replacement (showing the type of a file with perl)
by Corion (Pope) on Apr 17, 2012 at 12:44 UTC

    Usually, the file command relies on the "magic" bytes at the start of a file. Usually these signatures are stored in a file named /etc/magic. There are modules that either include such a database or can reuse such a file. Most are found by Magic (resp. MMagic for File::MMagic).

Re: file command replacement (showing the type of a file with perl)
by zwon (Monsignor) on Apr 17, 2012 at 13:26 UTC

    If you want same output as from file have a look at File::LibMagic, it uses the same library:

    $ file 1x1.png 1x1.png: PNG image data, 1 x 1, 8-bit/color RGBA, non-interlaced $ perl -MFile::LibMagic -E'say File::LibMagic->new->describe_filename( +"1x1.png")' PNG image data, 1 x 1, 8-bit/color RGBA, non-interlaced
Re: file command replacement (showing the type of a file with perl)
by pvaldes (Chaplain) on Apr 17, 2012 at 14:04 UTC

    Thank you very much for the replies, specially to halfcountplus for educate me and to Corion for point me (first) to the right trace

    I had tried File::MMagic but without success, it seems that is deprecated and some buggy. This is what you can read about the module in cpan:

    "The currently recommended module in this area seems to be File::LibMagic. Other alternatives include File::Type (gives less useful results)...

    Thus following the trace I finish to arrive to the same module recommmended by Zwon, (thanks also) that works like a charm

    # apt-get install libfile-libmagic-perl # (run this first once if you are in Debian) use File::LibMagic ':easy'; my $infile = $ARGV[0] print MagicFile($infile),"\n"; print `file $infile`;

    Last two lines show basically the same info when we provide a filename as first argument.

    Problem solved thus. Thanks again

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://965499]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (9)
As of 2014-12-27 19:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (177 votes), past polls