Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

How to concatenate binary files

by AnotherMonkWannabe (Initiate)
on Apr 12, 2005 at 20:43 UTC ( #447170=perlquestion: print w/replies, xml ) Need Help??
AnotherMonkWannabe has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone, This is my first post on this forum! hurrraaayy!! I am currently in the process of creating a program that, given a directory, it will automatically search for filenames with a given extension and concatenate them into one big file. Note that I am talking about binary concatenation. Can anybody give me some pointers as to how I can accomplish this (the concatenation part)? Thanx, AMW

Replies are listed 'Best First'.
Re: How to concatenate binary files
by ikegami (Pope) on Apr 12, 2005 at 21:02 UTC


    - Open the output file. - Use binmode on the output file handle. - For each input file to concatenate, - Open the next input file. - Use binmode on the input file handle. - While you haven't reached the end of the input file, - Read from the input file handle - Write what you read } }

    An untested sample Perl implementation:

    { # This code must be provided $output and $ext. local $/ = \4096; # Limit the size of our block. local *OUT; open(OUT, "> $output") or die("Can't create output file: $!"); binmode(OUT); local $_; while (glob("*.$ext")) { local *IN; open(IN, "< $_") or die("Can't open input file $_: $!"); binmode(IN); { local $_; print OUT $_ while <IN>; } } }

    A simple way of doing it from a DOS prompt, Windows prompt or a batch file (without using Perl):

    copy /b *.ext output

    A simple way of doing it from a *ix prompt (without using Perl):

    cat *.ext > output
Re: How to concatenate binary files
by Tanktalus (Canon) on Apr 12, 2005 at 21:38 UTC

    Here's my sub on creating self-extracting EXE's which may come in useful. Note that this works on both Windows and Unix/Linux, even though it's always creating a Windows-based self-extracting EXE. (I know - I developed it on Linux, and just ran tests on Windows to make sure it still worked.)

    use File::Copy; use IO::File; sub _create_sfx { my $self = shift; my $zip = shift; my $exe = shift; my $fh = IO::File->new($exe, "w"); binmode($fh); # stupid Windows copy(File::Spec->catfile(LocationOfUnzipsfxExe(), 'unzipsfx.exe'), $fh); copy($zip, $fh); unlink($zip); $fh->close(); system(qw(zip -A), $exe); }

    As you can see, I open my output filehandle, set it to binary mode, and use File::Copy::copy to copy each filename (the unzipsfx.exe file and the zip file) into my still-open file handle. Once closed, then I tell zip to fix the sfx executable (offsets and stuff), and we're done. Funny thing is that "zip -A" run on Linux ... works to create the Windows self-extractor. :-)

      I've never done this kind of thing, so this is a completely ignorant question: why don't you do the whole thing with a single call to zip -A, like this:

      my $sfx = File::Spec->catfile(LocationOfUnzipsfxExe(), 'unzipsfx.exe') +; system( qw( zip -A ), $exe, $sfx, $zip ) and die "$?"; unlink $zip;

      the lowliest monk

        That's a very good and interesting question. I suppose the reason why I did it the way above is because it's a perl interpretation of the unzipsfx docs (check the man page on unzipsfx - the EXAMPLES section near the bottom).

        A quick test shows:

        $ zip -A mysfx /usr/bin/unzipsfx x adding: usr/bin/unzipsfx (deflated 52%) adding: x (deflated 12%) $ file mysfx mysfx: Zip archive data, at least v2.0 to extract
        which is far from what we want. The output is still a zip file. But, if we do the shell version of the perl code above, we get:
        $ cat /usr/bin/unzipsfx mysfx > mysfx_exe $ zip -A mysfx_exe mysfx_exe: adjusting offsets for a preamble of 47552 bytes $ file mysfx_exe mysfx_exe: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), f +or GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped
        I hope that helps.

Re: How to concatenate binary files
by Sandy (Curate) on Apr 12, 2005 at 21:07 UTC
    This thread my be of help: How to concatenate the contents of two files?

    0. open file for input

    1. loop through files (use foreach ?)

    2. open file in binary mode (see documentation for 'open' command, and 'binmode') perldoc -f open
    ex:   open (FH, "<:raw", $myfile) or die "Oops: $!"

    3. read x number of bytes from file, using 'read' command (perldoc -f read)

    4. write what you have read to your 'new' file

    5. continue writing until end-of-file, loop for next input file.

Re: How to concatenate binary files
by brian_d_foy (Abbot) on Apr 12, 2005 at 22:37 UTC

    What sort of files are these? Is there extra garbage at the beginning or end of the files so you can't just join them?

    brian d foy <>

      brian, excuse my ignorance here, but I'm not sure what your question is. I believe the OP's question is how to "just join them". In perl. So, I'm not sure what you're getting at here.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://447170]
Approved by tlm
[Lotus1]: I was here

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (11)
As of 2018-06-18 17:53 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (110 votes). Check out past polls.