ruby archiver

M

Martin DeMello

Is there any pure-ruby way to pack multiple files into a single file,
and unpack them later? Compression is optional.

martin
 
R

Robert Klemme

Martin DeMello said:
Is there any pure-ruby way to pack multiple files into a single file,
and unpack them later? Compression is optional.

Dunno, but you could easily create one using Marshal. Experimental (works
only for text files and files that fit completely into memory):


def archive(archive, *files)
File.open(archive, "wb") do |io|
files.each do |file|
Marshal.dump(file, io)
Marshal.dump(File.read(file), io)
end
end
end

def unarchive(archive)
names = []
begin
File.open(archive, "rb") do |io|
file = Marshal.load( io )
File.open(file, "w") {|out| out.write( Marshal.load( io ) ) }
names << file
end
rescue EOFError
# ok, no more objects
end
names
end


archive( "test.rarc", "Rg.rb" )
File.rename "Rg.rb", "Rg-old.rb"
p unarchive( "test.rarc" )


robert
 
K

Kristof Bastiaensen

Is there any pure-ruby way to pack multiple files into a single file, and
unpack them later? Compression is optional.

martin

Something like this?

packing:
$ ruby pack.rb file1 file2 > my_package.rb

extracting:
$ ruby my_package.rb

the code:

#--- pack.rb ---
EXTRACT = <<EOF
numfiles = DATA.gets.to_i
files = []
numfiles.times do
files << [DATA.gets.chomp, DATA.gets.to_i]
end
numfiles.times do |i|
file, size = files
File.open(file, "w") { |f| f.write(DATA.read(size)) }
end
__END__
EOF

puts EXTRACT
puts ARGV.size
ARGV.each do |f|
puts f
puts File.size(f)
end
ARGV.each do |f|
STDOUT.write(IO.read(f))
end
# --- end pack.rb ---

Regards,
KB
 
A

Austin Ziegler

Is there any pure-ruby way to pack multiple files into a single file,
and unpack them later? Compression is optional.

As a matter of fact, you can use either Jamis Buck's tar.rb or my
forthcoming Archive::Tar::Minitar based on work by Mauricio Fernandez
(aka batsman). I'm putting some finishing touches on documentation and
the command line utility, but:

C:\home\Projects\minitar>ruby bin/minitar help commands
The commands known to minitar are:

minitar create Creates a new tarfile.
minitar extract Extracts files from a tarfile.
minitar list Lists files in the tarfile.

All commands accept the options --verbose and --progress, which are
mutually exclusive. In "minitar list", --progress means the same as
--verbose.

--verbose, -V Performs the requested command verbosely.
--progress, -P Shows a progress bar, if appropriate, for the action
being performed.

C:\home\Projects\minitar>ruby bin/minitar --progress create tests.tar tests
tests.tar: 100% |oooooooooooooooooooooooooooooooo| Time: 00:00:00

C:\home\Projects\minitar>ruby bin/minitar ls -l tests.tar
drwxr-xr-x 0 0 Sep 06 16:38 tests
-rw-r--r-- 38 19749 Sep 06 16:38 tests/tc_tar.rb
-rw-r--r-- 0 477 Aug 27 14:14 tests/testall.rb

C:\home\Projects\minitar>ruby bin/minitar --progress extract tests.tar -o tests2
tests.tar: 100% |oooooooooooooooooooooooooooooooooooooooooo| Time: 00:00:00

-austin
 
M

Mauricio Fernández

As a matter of fact, you can use either Jamis Buck's tar.rb or my
forthcoming Archive::Tar::Minitar based on work by Mauricio Fernandez
(aka batsman).

That code has the nice property of working with IO-like objects and
being able to operate in 'streaming mode' (i.e. no seek/rewind calls),
which means you can compress as you write the tar.

For instance, in rpa-base, the following is done in one step, with no
intermediate files

data files,
lots of them =====> tar ====> gzip data.tar.gz
\_____ tar ==> .rpa file
/
metadata =====> gzip metadata.gz

you add data files to the "inner tar", which outputs to a GZipWriter,
which writes into the outer tar, which is being written to disk.
 
A

Austin Ziegler

That code has the nice property of working with IO-like objects and
being able to operate in 'streaming mode' (i.e. no seek/rewind calls),
which means you can compress as you write the tar.

For instance, in rpa-base, the following is done in one step, with no
intermediate files

data files,
lots of them =====> tar ====> gzip data.tar.gz
\_____ tar ==> .rpa file
/
metadata =====> gzip metadata.gz

you add data files to the "inner tar", which outputs to a GZipWriter,
which writes into the outer tar, which is being written to disk.

This code is also going to be used in the deployment code for Ruwiki
(version forthcoming... I promise), and the only reason that I'm
actually making a release is it seemed pretty dumb to be making a
RubyGem/RPA release of Ruwiki that then packaged another piece of code
that could be set up as an automated dependency.

There are other steps that I need to take with the code that may prove
generally useful (imagine having a rakefile that can tar the files
with the time, date, and permissions that you want -- even if you
don't have a 'tar' program handy). If I can ever wrap my head around
rake enough, I will end up shifting some packaging code to do this ...
but understanding rake isn't something that's working for me right at
the moment.

-austin
 
M

Martin DeMello

Austin Ziegler said:
As a matter of fact, you can use either Jamis Buck's tar.rb or my
forthcoming Archive::Tar::Minitar based on work by Mauricio Fernandez
(aka batsman). I'm putting some finishing touches on documentation and
the command line utility, but:

Cool - this sounds like just what I need.

martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,413
Latest member
KeiraLight

Latest Threads

Top