1
20 package org.crosswire.common.util;
21
22 import java.io.Closeable;
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.net.MalformedURLException;
28 import java.net.URI;
29 import java.util.Enumeration;
30
31 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
32 import org.apache.commons.compress.archivers.zip.ZipFile;
33 import org.crosswire.jsword.JSMsg;
34 import org.slf4j.LoggerFactory;
35
36
42 public final class IOUtil {
43
46 private IOUtil() {
47 }
48
49
60 public static void unpackZip(File file, File destdir) throws IOException {
61 unpackZip(file, destdir, true);
62 }
63
64
79 public static void unpackZip(File file, File destdir, boolean include, String... includeExcludes) throws IOException {
80 byte[] dbuf = new byte[4096];
82 ZipFile zf = null;
83 try {
84 zf = new ZipFile(file);
85 Enumeration<ZipArchiveEntry> entries = zf.getEntries();
86 while (entries.hasMoreElements()) {
87 ZipArchiveEntry entry = entries.nextElement();
88 String entrypath = entry.getName();
89
90 if (includeExcludes != null && includeExcludes.length > 0) {
92 boolean skip = include;
95 for (String filter : includeExcludes) {
96 final boolean matchesPath = entrypath.toLowerCase().startsWith(filter);
97 if (include && matchesPath) {
99 skip = false;
100 }
101
102 if (!include && matchesPath) {
104 skip = true;
105 }
106 }
107
108 if (skip) {
109 continue;
110 }
111 }
112
113 File entryFile = new File(destdir, entrypath);
114 File parentDir = entryFile.getParentFile();
115 if (!parentDir.isDirectory()) {
117 if (!parentDir.mkdirs()) {
119 throw new MalformedURLException(JSMsg.gettext("The URL {0} could not be created as a directory.", parentDir.toString()));
121 }
122 }
123
124 if (!entry.isDirectory()) {
126
127 URI child = NetUtil.getURI(entryFile);
128
129 OutputStream dataOut = NetUtil.getOutputStream(child);
130 InputStream dataIn = zf.getInputStream(entry);
131
132 while (true) {
133 int count = dataIn.read(dbuf);
134 if (count == -1) {
135 break;
136 }
137 dataOut.write(dbuf, 0, count);
138 }
139
140 dataOut.close();
141 }
142 }
143 } finally {
144 IOUtil.close(zf);
145 }
146 }
147
148
156 public static byte[] getZipEntry(String entrySpec) throws IOException {
157 byte[] buffer = new byte[0];
159 String[] parts = StringUtil.split(entrySpec, '!');
160 ZipFile zipFile = null;
161 InputStream zin = null;
162 try {
163 zipFile = new ZipFile(parts[0]);
164 ZipArchiveEntry entry = zipFile.getEntry(parts[1]);
165 zin = zipFile.getInputStream(entry);
166 int size = (int) entry.getSize();
167 buffer = new byte[size];
168 int offset = 0;
170 while (offset < size) {
171 offset += zin.read(buffer, offset, size - offset);
172 }
173
174 if (offset != size) {
175 log.error("Error: Could not read {} bytes, instead {}, for {} from {}", Integer.toString(size), Integer.toString(offset), parts[1], parts[0]);
176 }
177 } finally {
178 IOUtil.close(zin);
179 IOUtil.close(zipFile);
180 }
181 return buffer;
182 }
183
184
190 public static void close(Closeable closeable) {
191 if (null != closeable) {
192 try {
193 closeable.close();
194 } catch (IOException ex) {
195 log.error("close", ex);
196 }
197 }
198 }
199
200
203 private static final org.slf4j.Logger log = LoggerFactory.getLogger(IOUtil.class);
204 }
205