| 5767 |
alewis |
1 |
=head1 NAME
|
|
|
2 |
|
|
|
3 |
Archive::Zip::FAQ - Answers to a few frequently asked questions about Archive::Zip
|
|
|
4 |
|
|
|
5 |
=head1 DESCRIPTION
|
|
|
6 |
|
|
|
7 |
It seems that I keep answering the same questions over and over again. I
|
|
|
8 |
assume that this is because my documentation is deficient, rather than that
|
|
|
9 |
people don't read the documentation.
|
|
|
10 |
|
|
|
11 |
So this FAQ is an attempt to cut down on the number of personal answers I have
|
|
|
12 |
to give. At least I can now say "You I<did> read the FAQ, right?".
|
|
|
13 |
|
|
|
14 |
The questions are not in any particular order. The answers assume the current
|
|
|
15 |
version of Archive::Zip; some of the answers depend on newly added/fixed
|
|
|
16 |
functionality.
|
|
|
17 |
|
|
|
18 |
=head1 Install problems on RedHat 8 or 9 with Perl 5.8.0
|
|
|
19 |
|
|
|
20 |
B<Q:> Archive::Zip won't install on my RedHat 9 system! It's broke!
|
|
|
21 |
|
|
|
22 |
B<A:> This has become something of a FAQ.
|
|
|
23 |
Basically, RedHat broke some versions of Perl by setting LANG to UTF8.
|
|
|
24 |
They apparently have a fixed version out as an update.
|
|
|
25 |
|
|
|
26 |
You might try running CPAN or creating your Makefile after exporting the LANG
|
|
|
27 |
environment variable as
|
|
|
28 |
|
|
|
29 |
C<LANG=C>
|
|
|
30 |
|
|
|
31 |
L<https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=87682>
|
|
|
32 |
|
|
|
33 |
=head1 Why is my zip file so big?
|
|
|
34 |
|
|
|
35 |
B<Q:> My zip file is actually bigger than what I stored in it! Why?
|
|
|
36 |
|
|
|
37 |
B<A:> Some things to make sure of:
|
|
|
38 |
|
|
|
39 |
=over 4
|
|
|
40 |
|
|
|
41 |
=item Make sure that you are requesting COMPRESSION_DEFLATED if you are storing strings.
|
|
|
42 |
|
|
|
43 |
$member->desiredCompressionMethod( COMPRESSION_DEFLATED );
|
|
|
44 |
|
|
|
45 |
=item Don't make lots of little files if you can help it.
|
|
|
46 |
|
|
|
47 |
Since zip computes the compression tables for each member, small
|
|
|
48 |
members without much entropy won't compress well. Instead, if you've
|
|
|
49 |
got lots of repeated strings in your data, try to combine them into
|
|
|
50 |
one big member.
|
|
|
51 |
|
|
|
52 |
=item Make sure that you are requesting COMPRESSION_STORED if you are storing things that are already compressed.
|
|
|
53 |
|
|
|
54 |
If you're storing a .zip, .jpg, .mp3, or other compressed file in a zip,
|
|
|
55 |
then don't compress them again. They'll get bigger.
|
|
|
56 |
|
|
|
57 |
=back
|
|
|
58 |
|
|
|
59 |
=head1 Sample code?
|
|
|
60 |
|
|
|
61 |
B<Q:> Can you send me code to do (whatever)?
|
|
|
62 |
|
|
|
63 |
B<A:> Have you looked in the C<examples/> directory yet? It contains:
|
|
|
64 |
|
|
|
65 |
=over 4
|
|
|
66 |
|
|
|
67 |
=item examples/calcSizes.pl -- How to find out how big a Zip file will be before writing it
|
|
|
68 |
|
|
|
69 |
=item examples/copy.pl -- Copies one Zip file to another
|
|
|
70 |
|
|
|
71 |
=item examples/extract.pl -- extract file(s) from a Zip
|
|
|
72 |
|
|
|
73 |
=item examples/mailZip.pl -- make and mail a zip file
|
|
|
74 |
|
|
|
75 |
=item examples/mfh.pl -- demo for use of MockFileHandle
|
|
|
76 |
|
|
|
77 |
=item examples/readScalar.pl -- shows how to use IO::Scalar as the source of a Zip read
|
|
|
78 |
|
|
|
79 |
=item examples/selfex.pl -- a brief example of a self-extracting Zip
|
|
|
80 |
|
|
|
81 |
=item examples/unzipAll.pl -- uses Archive::Zip::Tree to unzip an entire Zip
|
|
|
82 |
|
|
|
83 |
=item examples/updateZip.pl -- shows how to read/modify/write a Zip
|
|
|
84 |
|
|
|
85 |
=item examples/updateTree.pl -- shows how to update a Zip in place
|
|
|
86 |
|
|
|
87 |
=item examples/writeScalar.pl -- shows how to use IO::Scalar as the destination of a Zip write
|
|
|
88 |
|
|
|
89 |
=item examples/writeScalar2.pl -- shows how to use IO::String as the destination of a Zip write
|
|
|
90 |
|
|
|
91 |
=item examples/zip.pl -- Constructs a Zip file
|
|
|
92 |
|
|
|
93 |
=item examples/zipcheck.pl -- One way to check a Zip file for validity
|
|
|
94 |
|
|
|
95 |
=item examples/zipinfo.pl -- Prints out information about a Zip archive file
|
|
|
96 |
|
|
|
97 |
=item examples/zipGrep.pl -- Searches for text in Zip files
|
|
|
98 |
|
|
|
99 |
=item examples/ziptest.pl -- Lists a Zip file and checks member CRCs
|
|
|
100 |
|
|
|
101 |
=item examples/ziprecent.pl -- Puts recent files into a zipfile
|
|
|
102 |
|
|
|
103 |
=item examples/ziptest.pl -- Another way to check a Zip file for validity
|
|
|
104 |
|
|
|
105 |
=back
|
|
|
106 |
|
|
|
107 |
=head1 Can't Read/modify/write same Zip file
|
|
|
108 |
|
|
|
109 |
B<Q:> Why can't I open a Zip file, add a member, and write it back? I get an
|
|
|
110 |
error message when I try.
|
|
|
111 |
|
|
|
112 |
B<A:> Because Archive::Zip doesn't (and can't, generally) read file contents into memory,
|
|
|
113 |
the original Zip file is required to stay around until the writing of the new
|
|
|
114 |
file is completed.
|
|
|
115 |
|
|
|
116 |
The best way to do this is to write the Zip to a temporary file and then
|
|
|
117 |
rename the temporary file to have the old name (possibly after deleting the
|
|
|
118 |
old one).
|
|
|
119 |
|
|
|
120 |
Archive::Zip v1.02 added the archive methods C<overwrite()> and
|
|
|
121 |
C<overwriteAs()> to do this simply and carefully.
|
|
|
122 |
|
|
|
123 |
See C<examples/updateZip.pl> for an example of this technique.
|
|
|
124 |
|
|
|
125 |
=head1 File creation time not set
|
|
|
126 |
|
|
|
127 |
B<Q:> Upon extracting files, I see that their modification (and access) times are
|
|
|
128 |
set to the time in the Zip archive. However, their creation time is not set to
|
|
|
129 |
the same time. Why?
|
|
|
130 |
|
|
|
131 |
B<A:> Mostly because Perl doesn't give cross-platform access to I<creation time>.
|
|
|
132 |
Indeed, many systems (like Unix) don't support such a concept.
|
|
|
133 |
However, if yours does, you can easily set it. Get the modification time from
|
|
|
134 |
the member using C<lastModTime()>.
|
|
|
135 |
|
|
|
136 |
=head1 Can't use Archive::Zip on gzip files
|
|
|
137 |
|
|
|
138 |
B<Q:> Can I use Archive::Zip to extract Unix gzip files?
|
|
|
139 |
|
|
|
140 |
B<A:> No.
|
|
|
141 |
|
|
|
142 |
There is a distinction between Unix gzip files, and Zip archives that
|
|
|
143 |
also can use the gzip compression.
|
|
|
144 |
|
|
|
145 |
Depending on the format of the gzip file, you can use L<Compress::Raw::Zlib>, or
|
|
|
146 |
L<Archive::Tar> to decompress it (and de-archive it in the case of Tar files).
|
|
|
147 |
|
|
|
148 |
You can unzip PKZIP/WinZip/etc/ archives using Archive::Zip (that's what
|
|
|
149 |
it's for) as long as any compressed members are compressed using
|
|
|
150 |
Deflate compression.
|
|
|
151 |
|
|
|
152 |
=head1 Add a directory/tree to a Zip
|
|
|
153 |
|
|
|
154 |
B<Q:> How can I add a directory (or tree) full of files to a Zip?
|
|
|
155 |
|
|
|
156 |
B<A:> You can use the Archive::Zip::addTree*() methods:
|
|
|
157 |
|
|
|
158 |
use Archive::Zip;
|
|
|
159 |
my $zip = Archive::Zip->new();
|
|
|
160 |
# add all readable files and directories below . as xyz/*
|
|
|
161 |
$zip->addTree( '.', 'xyz' );
|
|
|
162 |
# add all readable plain files below /abc as def/*
|
|
|
163 |
$zip->addTree( '/abc', 'def', sub { -f && -r } );
|
|
|
164 |
# add all .c files below /tmp as stuff/*
|
|
|
165 |
$zip->addTreeMatching( '/tmp', 'stuff', '\.c$' );
|
|
|
166 |
# add all .o files below /tmp as stuff/* if they aren't writable
|
|
|
167 |
$zip->addTreeMatching( '/tmp', 'stuff', '\.o$', sub { ! -w } );
|
|
|
168 |
# add all .so files below /tmp that are smaller than 200 bytes as stuff/*
|
|
|
169 |
$zip->addTreeMatching( '/tmp', 'stuff', '\.o$', sub { -s < 200 } );
|
|
|
170 |
# and write them into a file
|
|
|
171 |
$zip->writeToFileNamed('xxx.zip');
|
|
|
172 |
|
|
|
173 |
=head1 Extract a directory/tree
|
|
|
174 |
|
|
|
175 |
B<Q:> How can I extract some (or all) files from a Zip into a different
|
|
|
176 |
directory?
|
|
|
177 |
|
|
|
178 |
B<A:> You can use the Archive::Zip::extractTree() method:
|
|
|
179 |
??? ||
|
|
|
180 |
|
|
|
181 |
# now extract the same files into /tmpx
|
|
|
182 |
$zip->extractTree( 'stuff', '/tmpx' );
|
|
|
183 |
|
|
|
184 |
=head1 Update a directory/tree
|
|
|
185 |
|
|
|
186 |
B<Q:> How can I update a Zip from a directory tree, adding or replacing only
|
|
|
187 |
the newer files?
|
|
|
188 |
|
|
|
189 |
B<A:> You can use the Archive::Zip::updateTree() method that was added in version 1.09.
|
|
|
190 |
|
|
|
191 |
=head1 Zip times might be off by 1 second
|
|
|
192 |
|
|
|
193 |
B<Q:> It bothers me greatly that my file times are wrong by one second about half
|
|
|
194 |
the time. Why don't you do something about it?
|
|
|
195 |
|
|
|
196 |
B<A:> Get over it. This is a result of the Zip format storing times in DOS
|
|
|
197 |
format, which has a resolution of only two seconds.
|
|
|
198 |
|
|
|
199 |
=head1 Zip times don't include time zone information
|
|
|
200 |
|
|
|
201 |
B<Q:> My file times don't respect time zones. What gives?
|
|
|
202 |
|
|
|
203 |
B<A:> If this is important to you, please submit patches to read the various
|
|
|
204 |
Extra Fields that encode times with time zones. I'm just using the DOS
|
|
|
205 |
Date/Time, which doesn't have a time zone.
|
|
|
206 |
|
|
|
207 |
=head1 How do I make a self-extracting Zip
|
|
|
208 |
|
|
|
209 |
B<Q:> I want to make a self-extracting Zip file. Can I do this?
|
|
|
210 |
|
|
|
211 |
B<A:> Yes. You can write a self-extracting archive stub (that is, a version of
|
|
|
212 |
unzip) to the output filehandle that you pass to writeToFileHandle(). See
|
|
|
213 |
examples/selfex.pl for how to write a self-extracting archive.
|
|
|
214 |
|
|
|
215 |
However, you should understand that this will only work on one kind of
|
|
|
216 |
platform (the one for which the stub was compiled).
|
|
|
217 |
|
|
|
218 |
=head1 How can I deal with Zips with prepended garbage (i.e. from Sircam)
|
|
|
219 |
|
|
|
220 |
B<Q:> How can I tell if a Zip has been damaged by adding garbage to the
|
|
|
221 |
beginning or inside the file?
|
|
|
222 |
|
|
|
223 |
B<A:> I added code for this for the Amavis virus scanner. You can query archives
|
|
|
224 |
for their 'eocdOffset' property, which should be 0:
|
|
|
225 |
|
|
|
226 |
if ($zip->eocdOffset > 0)
|
|
|
227 |
{ warn($zip->eocdOffset . " bytes of garbage at beginning or within Zip") }
|
|
|
228 |
|
|
|
229 |
When members are extracted, this offset will be used to adjust the start of
|
|
|
230 |
the member if necessary.
|
|
|
231 |
|
|
|
232 |
=head1 Can't extract Shrunk files
|
|
|
233 |
|
|
|
234 |
B<Q:> I'm trying to extract a file out of a Zip produced by PKZIP, and keep
|
|
|
235 |
getting this error message:
|
|
|
236 |
|
|
|
237 |
error: Unsupported compression combination: read 6, write 0
|
|
|
238 |
|
|
|
239 |
B<A:> You can't uncompress this archive member. Archive::Zip only supports uncompressed
|
|
|
240 |
members, and compressed members that are compressed using the compression
|
|
|
241 |
supported by Compress::Raw::Zlib. That means only Deflated and Stored members.
|
|
|
242 |
|
|
|
243 |
Your file is compressed using the Shrink format, which is not supported by
|
|
|
244 |
Compress::Raw::Zlib.
|
|
|
245 |
|
|
|
246 |
You could, perhaps, use a command-line UnZip program (like the Info-Zip
|
|
|
247 |
one) to extract this.
|
|
|
248 |
|
|
|
249 |
=head1 Can't do decryption
|
|
|
250 |
|
|
|
251 |
B<Q:> How do I decrypt encrypted Zip members?
|
|
|
252 |
|
|
|
253 |
B<A:> With some other program or library. Archive::Zip doesn't support decryption,
|
|
|
254 |
and probably never will (unless I<you> write it).
|
|
|
255 |
|
|
|
256 |
=head1 How to test file integrity?
|
|
|
257 |
|
|
|
258 |
B<Q:> How can Archive::Zip can test the validity of a Zip file?
|
|
|
259 |
|
|
|
260 |
B<A:> If you try to decompress the file, the gzip streams will report errors
|
|
|
261 |
if you have garbage. Most of the time.
|
|
|
262 |
|
|
|
263 |
If you try to open the file and a central directory structure can't be
|
|
|
264 |
found, an error will be reported.
|
|
|
265 |
|
|
|
266 |
When a file is being read, if we can't find a proper PK.. signature in
|
|
|
267 |
the right places we report a format error.
|
|
|
268 |
|
|
|
269 |
If there is added garbage at the beginning of a Zip file (as inserted
|
|
|
270 |
by some viruses), you can find out about it, but Archive::Zip will ignore it,
|
|
|
271 |
and you can still use the archive. When it gets written back out the
|
|
|
272 |
added stuff will be gone.
|
|
|
273 |
|
|
|
274 |
There are two ready-to-use utilities in the examples directory that can
|
|
|
275 |
be used to test file integrity, or that you can use as examples
|
|
|
276 |
for your own code:
|
|
|
277 |
|
|
|
278 |
=over 4
|
|
|
279 |
|
|
|
280 |
=item examples/zipcheck.pl shows how to use an attempted extraction to test a file.
|
|
|
281 |
|
|
|
282 |
=item examples/ziptest.pl shows how to test CRCs in a file.
|
|
|
283 |
|
|
|
284 |
=back
|
|
|
285 |
|
|
|
286 |
=head1 Duplicate files in Zip?
|
|
|
287 |
|
|
|
288 |
B<Q:> Archive::Zip let me put the same file in my Zip twice! Why don't you prevent this?
|
|
|
289 |
|
|
|
290 |
B<A:> As far as I can tell, this is not disallowed by the Zip spec. If you
|
|
|
291 |
think it's a bad idea, check for it yourself:
|
|
|
292 |
|
|
|
293 |
$zip->addFile($someFile, $someName) unless $zip->memberNamed($someName);
|
|
|
294 |
|
|
|
295 |
I can even imagine cases where this might be useful (for instance, multiple
|
|
|
296 |
versions of files).
|
|
|
297 |
|
|
|
298 |
=head1 File ownership/permissions/ACLS/etc
|
|
|
299 |
|
|
|
300 |
B<Q:> Why doesn't Archive::Zip deal with file ownership, ACLs, etc.?
|
|
|
301 |
|
|
|
302 |
B<A:> There is no standard way to represent these in the Zip file format. If
|
|
|
303 |
you want to send me code to properly handle the various extra fields that
|
|
|
304 |
have been used to represent these through the years, I'll look at it.
|
|
|
305 |
|
|
|
306 |
=head1 I can't compile but ActiveState only has an old version of Archive::Zip
|
|
|
307 |
|
|
|
308 |
B<Q:> I've only installed modules using ActiveState's PPM program and
|
|
|
309 |
repository. But they have a much older version of Archive::Zip than is in CPAN. Will
|
|
|
310 |
you send me a newer PPM?
|
|
|
311 |
|
|
|
312 |
B<A:> Probably not, unless I get lots of extra time. But there's no reason you
|
|
|
313 |
can't install the version from CPAN. Archive::Zip is pure Perl, so all you need is
|
|
|
314 |
NMAKE, which you can get for free from Microsoft (see the FAQ in the
|
|
|
315 |
ActiveState documentation for details on how to install CPAN modules).
|
|
|
316 |
|
|
|
317 |
=head1 My JPEGs (or MP3's) don't compress when I put them into Zips!
|
|
|
318 |
|
|
|
319 |
B<Q:> How come my JPEGs and MP3's don't compress much when I put them into Zips?
|
|
|
320 |
|
|
|
321 |
B<A:> Because they're already compressed.
|
|
|
322 |
|
|
|
323 |
=head1 Under Windows, things lock up/get damaged
|
|
|
324 |
|
|
|
325 |
B<Q:> I'm using Windows. When I try to use Archive::Zip, my machine locks up/makes
|
|
|
326 |
funny sounds/displays a BSOD/corrupts data. How can I fix this?
|
|
|
327 |
|
|
|
328 |
B<A:> First, try the newest version of Compress::Raw::Zlib. I know of
|
|
|
329 |
Windows-related problems prior to v1.14 of that library.
|
|
|
330 |
|
|
|
331 |
=head1 Zip contents in a scalar
|
|
|
332 |
|
|
|
333 |
B<Q:> I want to read a Zip file from (or write one to) a scalar variable instead
|
|
|
334 |
of a file. How can I do this?
|
|
|
335 |
|
|
|
336 |
B<A:> Use C<IO::String> and the C<readFromFileHandle()> and
|
|
|
337 |
C<writeToFileHandle()> methods.
|
|
|
338 |
See C<examples/readScalar.pl> and C<examples/writeScalar.pl>.
|
|
|
339 |
|
|
|
340 |
=head1 Reading from streams
|
|
|
341 |
|
|
|
342 |
B<Q:> How do I read from a stream (like for the Info-Zip C<funzip> program)?
|
|
|
343 |
|
|
|
344 |
B<A:> This is not currently supported, though writing to a stream is.
|