1 17 package com.Ostermiller.util; 18 19 import java.io.*; 20 import java.util.*; 21 22 30 public class ConcatInputStream extends InputStream { 31 32 33 38 private int inputStreamQueueIndex = 0; 39 40 45 private ArrayList<InputStream> inputStreamQueue = new ArrayList<InputStream>(); 46 47 54 private InputStream currentInputStream = null; 55 56 61 private boolean doneAddingInputStreams = false; 62 63 73 public void lastInputStreamAdded(){ 74 doneAddingInputStreams = true; 75 } 76 77 86 public void addInputStream(InputStream in){ 87 synchronized(inputStreamQueue){ 88 if (in == null) throw new NullPointerException (); 89 if (closed) throw new IllegalStateException ("ConcatInputStream has been closed"); 90 if (doneAddingInputStreams) throw new IllegalStateException ("Cannot add more inputStreams - the last inputStream has already been added."); 91 inputStreamQueue.add(in); 92 } 93 } 94 95 105 public void addInputStreams(InputStream[] in){ 106 for (int i=0; i<in.length; i++){ 107 addInputStream(in[i]); 108 } 109 } 110 111 117 private InputStream getCurrentInputStream(){ 118 if (currentInputStream == null && inputStreamQueueIndex < inputStreamQueue.size()){ 119 synchronized(inputStreamQueue){ 120 currentInputStream = (InputStream)inputStreamQueue.get(inputStreamQueueIndex); 123 } 124 } 125 return currentInputStream; 126 } 127 128 134 private void advanceToNextInputStream(){ 135 currentInputStream = null; 136 inputStreamQueueIndex++; 137 } 138 139 144 private boolean closed = false; 145 146 147 158 public ConcatInputStream(){ 159 } 160 161 170 public ConcatInputStream(InputStream in){ 171 addInputStream(in); 172 lastInputStreamAdded(); 173 } 174 175 185 public ConcatInputStream(InputStream in1, InputStream in2){ 186 addInputStream(in1); 187 addInputStream(in2); 188 lastInputStreamAdded(); 189 } 190 191 200 public ConcatInputStream(InputStream[] in){ 201 addInputStreams(in); 202 lastInputStreamAdded(); 203 } 204 205 220 public int read() throws IOException { 221 if (closed) throw new IOException("InputStream closed"); 222 int r = -1; 223 while (r == -1){ 224 InputStream in = getCurrentInputStream(); 225 if (in == null){ 226 if (doneAddingInputStreams) return -1; 227 try { 228 Thread.sleep(100); 229 } catch (InterruptedException iox){ 230 throw new IOException("Interrupted"); 231 } 232 } else { 233 r = in.read(); 234 if (r == -1) advanceToNextInputStream(); 235 } 236 } 237 return r; 238 } 239 240 265 public int read(byte[] b) throws IOException { 266 return read(b, 0, b.length); 267 } 268 269 293 public int read(byte[] b, int off, int len) throws IOException { 294 if (off < 0 || len < 0 || off + len > b.length) throw new IllegalArgumentException (); 295 if (closed) throw new IOException("InputStream closed"); 296 int r = -1; 297 while (r == -1){ 298 InputStream in = getCurrentInputStream(); 299 if (in == null){ 300 if (doneAddingInputStreams) return -1; 301 try { 302 Thread.sleep(100); 303 } catch (InterruptedException iox){ 304 throw new IOException("Interrupted"); 305 } 306 } else { 307 r = in.read(b, off, len); 308 if (r == -1) advanceToNextInputStream(); 309 } 310 } 311 return r; 312 } 313 314 332 public long skip(long n) throws IOException { 333 if (closed) throw new IOException("InputStream closed"); 334 if (n <= 0) return 0; 335 long s = -1; 336 while (s <= 0){ 337 InputStream in = getCurrentInputStream(); 338 if (in == null){ 339 if (doneAddingInputStreams) return 0; 340 try { 341 Thread.sleep(100); 342 } catch (InterruptedException iox){ 343 throw new IOException("Interrupted"); 344 } 345 } else { 346 s = in.skip(n); 347 if (s <= 0) { 357 s = ((read()==-1)?-1:1); 359 } 360 } 361 362 } 363 return s; 364 } 365 366 375 public int available() throws IOException { 376 if (closed) throw new IOException("InputStream closed"); 377 InputStream in = getCurrentInputStream(); 378 if (in == null) return 0; 379 return in.available(); 380 } 381 382 387 public void close() throws IOException { 388 if (closed) return; 389 for (Iterator i=inputStreamQueue.iterator(); i.hasNext();){ 390 ((InputStream)i.next()).close(); 391 } 392 closed = true; 393 } 394 395 400 public void mark(int readlimit){ 401 } 402 403 410 public void reset() throws IOException { 411 throw new IOException("Reset not supported"); 412 } 413 414 421 public boolean markSupported(){ 422 return false; 423 } 424 } 425 | Popular Tags |