1 18 package com.izforge.izpack.io; 19 20 import java.io.File ; 21 import java.io.FileOutputStream ; 22 import java.io.IOException ; 23 import java.io.OutputStream ; 24 import java.util.zip.GZIPOutputStream ; 25 26 import com.izforge.izpack.util.Debug; 27 28 34 public class FileSpanningOutputStream extends OutputStream 35 { 36 37 public static final long KB = 1024; 38 39 public static final long MB = 1024 * KB; 40 41 public static final long DEFAULT_VOLUME_SIZE = 650 * MB; 43 44 public static final long DEFAULT_ADDITIONAL_FIRST_VOLUME_FREE_SPACE_SIZE = 0; 48 49 protected static final String DEFAULT_VOLUME_NAME = "installer"; 51 52 protected static final long FILE_NOT_AVAILABLE = -1; 53 54 protected long maxvolumesize = DEFAULT_VOLUME_SIZE; 56 57 protected long firstvolumefreespacesize = DEFAULT_ADDITIONAL_FIRST_VOLUME_FREE_SPACE_SIZE; 59 60 public static final String VOLUMES_INFO = "/volumes.info"; 61 62 protected File currentfile; 64 65 protected String volumename; 67 68 protected int currentvolumeindex; 70 71 private FileOutputStream fileoutputstream; 73 74 private GZIPOutputStream zippedoutputstream; 75 76 protected long filepointer; 78 79 protected long totalbytesofpreviousvolumes; 80 81 88 public FileSpanningOutputStream(String volumename, long maxvolumesize) throws IOException 89 { 90 this(new File (volumename), maxvolumesize); 91 } 92 93 100 public FileSpanningOutputStream(File volume, long maxvolumesize) throws IOException 101 { 102 this(volume, maxvolumesize, 0); 103 } 104 105 113 protected FileSpanningOutputStream(File volume, long maxvolumesize, int currentvolume) 114 throws IOException 115 { 116 this.createVolumeOutputStream(volume, maxvolumesize, currentvolume); 117 } 118 119 128 private void createVolumeOutputStream(File volume, long maxvolumesize, int currentvolume) 129 throws IOException 130 { 131 fileoutputstream = new FileOutputStream (volume); 132 zippedoutputstream = new GZIPOutputStream (fileoutputstream, 256); 133 currentfile = volume; 134 this.currentvolumeindex = currentvolume; 135 this.maxvolumesize = maxvolumesize; 136 String volumesuffix = "." + currentvolume; 139 String volabsolutePath = volume.getAbsolutePath(); 140 if (volabsolutePath.endsWith(volumesuffix)) 141 { 142 volumename = volabsolutePath.substring(0, volabsolutePath.indexOf(volumesuffix)); 143 } 144 else 145 { 146 volumename = volabsolutePath; 147 } 148 } 149 150 155 public FileSpanningOutputStream(File volume) throws IOException 156 { 157 this(volume.getAbsolutePath(), DEFAULT_VOLUME_SIZE); 158 } 159 160 165 public FileSpanningOutputStream(String volumename) throws IOException 166 { 167 this(volumename, DEFAULT_VOLUME_SIZE); 168 } 169 170 174 public FileSpanningOutputStream() throws IOException 175 { 176 this(DEFAULT_VOLUME_NAME, DEFAULT_VOLUME_SIZE); 177 } 178 179 184 protected long getCurrentVolumeSize() 185 { 186 if (currentfile == null) { return FILE_NOT_AVAILABLE; } 187 try 188 { 189 flush(); 190 } 191 catch (IOException e) 192 { 193 e.printStackTrace(); 194 } 195 currentfile = new File (currentfile.getAbsolutePath()); 197 if (currentvolumeindex == 0) 198 { 199 return currentfile.length() + this.firstvolumefreespacesize 202 + Math.round(0.001 * currentfile.length()); 203 } 204 else 205 { 206 return currentfile.length() + Math.round(0.001 * currentfile.length()); 209 } 210 } 211 212 217 protected void createStreamToNextVolume() throws IOException 218 { 219 close(); 221 totalbytesofpreviousvolumes = currentfile.length(); 222 currentvolumeindex++; 223 String nextvolumename = volumename + "." + currentvolumeindex; 225 this.createVolumeOutputStream(new File (nextvolumename), this.maxvolumesize, 227 this.currentvolumeindex); 228 } 229 230 233 public void close() throws IOException 234 { 235 this.flush(); 236 zippedoutputstream.close(); 237 fileoutputstream.close(); 238 } 241 242 245 public void write(byte[] b, int off, int len) throws IOException 246 { 247 if (len > maxvolumesize) { throw new IOException ( 248 "file can't be written. buffer length exceeded maxvolumesize (" + " > " 249 + maxvolumesize + ")"); } 250 long currentsize = getCurrentVolumeSize(); 252 long available = maxvolumesize - currentsize; 254 255 if (available < len) 256 { 257 Debug.trace("Not enough space left on volume. available: " + available); 258 Debug.trace("current size is: " + currentsize); 259 this.createStreamToNextVolume(); 262 } 263 zippedoutputstream.write(b, off, len); 265 filepointer += len; 267 } 268 269 272 public void write(byte[] b) throws IOException 273 { 274 this.write(b, 0, b.length); 275 } 276 277 280 public void write(int b) throws IOException 281 { 282 long availablebytes = maxvolumesize - getCurrentVolumeSize(); 283 if (availablebytes >= 1) 284 { 285 zippedoutputstream.write(b); 286 filepointer++; 288 } 289 else 290 { 291 this.createStreamToNextVolume(); 293 zippedoutputstream.write(b); 294 filepointer++; 296 } 297 } 298 299 302 public void flush() throws IOException 303 { 304 zippedoutputstream.flush(); 305 fileoutputstream.flush(); 306 } 307 308 313 public int getVolumeCount() 314 { 315 return this.currentvolumeindex + 1; 316 } 317 318 322 public long getFirstvolumefreespacesize() 323 { 324 return firstvolumefreespacesize; 325 } 326 327 331 public void setFirstvolumefreespacesize(long firstvolumefreespacesize) 332 { 333 this.firstvolumefreespacesize = firstvolumefreespacesize; 334 } 335 336 342 public long getCompressedFilepointer() throws IOException 343 { 344 this.flush(); 345 return totalbytesofpreviousvolumes + currentfile.length(); 347 } 348 349 public long getFilepointer() 350 { 351 return filepointer; 352 } 353 } 354 | Popular Tags |