1 30 31 package com.nightlabs.io; 32 33 import java.io.*; 34 import java.io.FileNotFoundException ; 35 import java.io.IOException ; 36 37 41 public class DataBuffer { 43 protected static int defaultMaxSizeForRAM = 4 * 1024 * 1024; 46 protected static byte MODE_RAM = 0; 47 protected static byte MODE_FILE = 1; 48 protected byte mode = MODE_RAM; 49 50 public long expectedSize; 51 public int maxSizeForRAM; 52 53 protected byte[] data; 54 55 protected File file = null; 56 59 protected long length = 0; 60 61 62 65 69 private byte[] oneByteByteArray = new byte[1]; 70 71 78 public DataBuffer() 79 throws FileNotFoundException , IOException 80 { 81 this(1024); 82 } 83 84 public DataBuffer(long expectedSize, String _fileName) 85 throws FileNotFoundException , 86 IOException 87 { 88 this(expectedSize, defaultMaxSizeForRAM, new File(_fileName)); 89 } 90 91 public DataBuffer(long expectedSize, File _file) 92 throws FileNotFoundException , 93 IOException 94 { 95 this(expectedSize, defaultMaxSizeForRAM, _file); 96 } 97 98 public DataBuffer(long expectedSize, int maxSizeForRAM, String _fileName) 99 throws FileNotFoundException , 100 IOException 101 { 102 this(expectedSize, maxSizeForRAM, new File(_fileName)); 103 } 104 105 public DataBuffer(long expectedSize, int maxSizeForRAM, File _file) 106 throws FileNotFoundException , 107 IOException 108 { 109 this.expectedSize = expectedSize; 110 this.maxSizeForRAM = maxSizeForRAM; 111 this.file = _file; 112 113 if (expectedSize > maxSizeForRAM || (file != null && file.exists())) 114 this.mode = MODE_FILE; 115 116 if (this.mode == MODE_FILE) { 117 if (file == null) 118 file = File.createTempFile("DataBuffer", ".tmp"); 119 120 length = file.length(); 121 } 122 else { 123 data = new byte[(int)expectedSize]; 124 } 125 } 126 127 134 public DataBuffer(long expectedSize) 149 throws FileNotFoundException , 150 IOException 151 { 152 this(expectedSize, defaultMaxSizeForRAM, (File)null); 153 } 154 155 156 protected FileInputStream createFileInputStream() 157 throws FileNotFoundException 158 { 159 if (mode != MODE_FILE) 160 throw new IllegalStateException ("Cannot return a FileInputStream when not in MODE_FILE!"); 161 162 return new FileInputStream(file); 163 } 164 165 174 public InputStream createInputStream() 175 throws IOException 176 { 177 if (mode == MODE_FILE) 178 return new BufferedInputStream(new FileInputStream(file)); 179 else 180 return new DataBufferInputStream(this); 181 } 182 183 195 public OutputStream createOutputStream() 196 throws IOException 197 { 198 return new DataBufferOutputStream(this); 202 } 203 204 protected void switchModeToFile() 205 throws IOException 206 { 207 if (mode == MODE_FILE) 208 return; 209 210 if (file == null) 211 file = File.createTempFile("DataBuffer", ".tmp"); 212 213 os = new BufferedOutputStream(new FileOutputStream(file, false)); 214 215 if (length > Integer.MAX_VALUE) 216 throw new IllegalStateException ("length is too big! Switching mode to file should have happened earlier!"); 217 218 os.write(data, 0, (int)length); 219 mode = MODE_FILE; 220 data = null; } 222 223 OutputStream os = null; 224 protected void closeOutputStream() 225 throws IOException 226 { 227 if (os != null) { 228 os.close(); 229 os = null; 230 } 231 } 232 233 protected void flushOutputStream() 234 throws IOException 235 { 236 if (os != null) 237 os.flush(); 238 } 239 240 protected void write(byte[] b, int off, int len) 241 throws IOException 242 { 243 if (mode == MODE_FILE) { 244 if (os == null) 245 os = new FileOutputStream(file, true); 246 247 os.write(b, off, len); 248 } else { 250 251 254 if (length + len > maxSizeForRAM) { 255 switchModeToFile(); 256 os.write(b, off, len); 257 } 258 else { 259 260 if (data.length < length + len) { 261 byte[] tmpData = new byte[((int)length + len) * 8 / 6]; System.arraycopy(data, 0, tmpData, 0, (int)length); 263 data = tmpData; 264 } 265 266 System.arraycopy(b, off, data, (int)length, len); 267 } 268 } 270 length += len; 271 } 272 273 public long size() 337 { 338 return length; 339 } 340 440 public void vomitFile(String dest) 441 throws IOException 442 { 443 vomitFile(new File(dest)); 444 } 445 446 public void vomitFile(File dest) 447 throws IOException 448 { 449 this.closeOutputStream(); 450 451 FileOutputStream o = new FileOutputStream(dest); 452 453 if (data != null) { 454 o.write(data); 455 } 456 else { 457 FileInputStream i = new FileInputStream(this.file); 458 byte[] b = new byte[8192]; 459 int bytesRead; 460 while (true) { 461 bytesRead = i.read(b); 462 if (bytesRead <= 0) 463 break; 464 465 o.write(b, 0, bytesRead); 466 } 467 468 } 469 470 o.close(); 471 } 472 473 481 public byte[] createByteArray() 482 throws IOException 483 { 484 if (length > Integer.MAX_VALUE) 485 throw new ArrayIndexOutOfBoundsException ("This DataBuffer contains too much data for a byte array!"); 486 487 byte[] res = new byte[(int)length]; 488 489 if (mode == MODE_RAM) { 490 System.arraycopy(data, 0, res, 0, res.length); 491 } 492 else if (mode == MODE_FILE) { 493 InputStream in = createInputStream(); 494 try { 495 int pos = 0; 496 int bytesRead; 497 do { 498 bytesRead = in.read(res, pos, res.length - pos); 499 if (bytesRead > 0) 500 pos += bytesRead; 501 } while (bytesRead >= 0 && pos < res.length); 502 if (pos < res.length) 503 throw new IOException ("Could not read all bytes (stream broken): pos < res.length!"); 504 } finally { 505 in.close(); 506 } 507 } 508 else 509 throw new IllegalStateException ("unknown mode: " + mode); 510 511 return res; 512 } 513 514 544 } 545 | Popular Tags |