00001 package net.threebit.utils.sosc;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 import javax.xml.transform.*;
00023 import javax.xml.transform.stream.*;
00024 import java.sql.*;
00025 import java.io.*;
00026 import java.util.*;
00027 import java.util.zip.*;
00028 import java.util.logging.*;
00029 import javax.servlet.http.*;
00030 import javax.servlet.jsp.*;
00031 import java.util.logging.*;
00032
00038 public class ZipTool {
00039
00041 Logger logger = Logger.getLogger("net.threebit.utils.sosc");
00042
00044 private ZipOutputStream zout;
00045
00047 private CRC32 crc = new CRC32();
00048
00050 private byte[] buffer = new byte[250 * 1024];
00051
00053 private PipedOutputStream pipedOutputStream = new PipedOutputStream();
00054
00056 private PipedInputStream pipedInputStream = null;
00057
00059 private int compressionLevel = Deflater.NO_COMPRESSION;
00060
00066 public ZipTool (int compressionLevel) throws IOException {
00067 this.compressionLevel = compressionLevel;
00068 pipedInputStream = new PipedInputStream(pipedOutputStream);
00069 zout = new ZipOutputStream(pipedOutputStream);
00070 zout.setLevel(compressionLevel);
00071 }
00072
00076 public InputStream getInputStream() {
00077 return pipedInputStream;
00078 }
00079
00083 public void close() throws IOException {
00084 zout.close();
00085 }
00086
00090 public void addFile (InputStream fis1, String path) throws IOException {
00091
00092
00093 synchronized (zout) {
00094
00095
00096 long size = 0;
00097
00098
00099 int len;
00100
00101
00102 ZipEntry entry;
00103
00104
00105 OutputStreamCounter counter = new OutputStreamCounter();
00106
00107
00108 Deflater deflater = new Deflater(compressionLevel, true);
00109
00110
00111 DeflaterOutputStream dout = new DeflaterOutputStream(counter, deflater);
00112
00113
00114 File tempFile = File.createTempFile("ZipToolTempFile","zip");
00115 FileOutputStream fout = new FileOutputStream(tempFile);
00116
00117
00118 crc.reset();
00119 while ((len = fis1.read(buffer)) >= 0)
00120 {
00121 size += len;
00122 crc.update(buffer, 0, len);
00123 dout.write(buffer, 0, len);
00124 fout.write(buffer, 0, len);
00125 }
00126 fis1.close();
00127 dout.close();
00128 fout.close();
00129
00130
00131 entry = new ZipEntry(path);
00132 entry.setSize(size);
00133 entry.setCompressedSize(counter.getSize());
00134 entry.setCrc(crc.getValue());
00135
00136
00137 FileInputStream fis2 = new FileInputStream(tempFile);
00138 zout.putNextEntry(entry);
00139 int size2 = 0;
00140 while ((len = fis2.read(buffer)) >= 0) {
00141 size2 += len;
00142 zout.write(buffer, 0, len);
00143 }
00144 fis2.close();
00145 zout.closeEntry();
00146
00147 tempFile.delete();
00148 if (size != size2) { throw new RuntimeException("Assertion failure; size: " + size + " size2: " + size2); }
00149 }
00150 }
00151
00155 static class OutputStreamCounter extends OutputStream
00156 {
00157 long count;
00158
00159 public void write(int b)
00160 {
00161 count++;
00162 }
00163
00164 public void write(byte[] buffer)
00165 {
00166 count += buffer.length;
00167 }
00168
00169 public void write(byte[] buffer, int offset, int length)
00170 {
00171 count += length;
00172 }
00173
00174 public long getSize()
00175 {
00176 return count;
00177 }
00178 }
00179
00180 }