Quadcap Embeddable Server

com/quadcap/io/SaveRestoreStream.java

Go to the documentation of this file.
00001 package com.quadcap.io; 00002 00003 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.ByteArrayInputStream; 00042 import java.io.ByteArrayOutputStream; 00043 import java.io.File; 00044 import java.io.FileInputStream; 00045 import java.io.FileNotFoundException; 00046 import java.io.FileOutputStream; 00047 import java.io.InputStream; 00048 import java.io.IOException; 00049 import java.io.OutputStream; 00050 00051 /** 00052 * This class implements a simple persistent object which can be written 00053 * as an OutputStream and read as an InputStream. Small objects can be 00054 * stored in memory, larger objects can be stored in temp files on disk. 00055 * 00056 * @author Stan Bailes 00057 */ 00058 public class SaveRestoreStream { 00059 ByteArrayOutputStream bos = null; 00060 FileOutputStream fos = null; 00061 File file = null; 00062 int len = 0; 00063 int max = 4096; 00064 00065 /** 00066 * Construct a new SaveRestoreStream with the default max buffered 00067 */ 00068 public SaveRestoreStream() { 00069 } 00070 00071 /** 00072 * Construct a new SaveRestoreStream with the specified max buffered 00073 * size. 00074 * 00075 * @param max the maximum amount of data to be buffered in memory. 00076 */ 00077 public SaveRestoreStream(int max) { 00078 this.max = max; 00079 } 00080 00081 /** 00082 * Construct a new SaveRestoreStream using the data in the specified 00083 * InputStream. 00084 * 00085 * @param in the InputStream supplying the data for this stream 00086 */ 00087 public SaveRestoreStream(InputStream in) throws IOException { 00088 OutputStream out = getOutputStream(); 00089 try { 00090 IO.copyStream(in, out); 00091 } finally { 00092 out.close(); 00093 } 00094 } 00095 00096 /** 00097 * Return an output stream that the caller can use to save his object 00098 * 00099 * @return the output stream 00100 */ 00101 public OutputStream getOutputStream() throws IOException { 00102 if (file == null) { 00103 bos = new ByteArrayOutputStream(); 00104 if (fos != null) fos.close(); 00105 fos = null; 00106 } else { 00107 bos = null; 00108 fos = new FileOutputStream(file); 00109 } 00110 00111 return new OutputStream() { 00112 public void write(int c) throws IOException { 00113 doWrite(c); 00114 } 00115 public void flush() throws IOException { 00116 if (bos != null) bos.flush(); 00117 else fos.flush(); 00118 } 00119 public void close() throws IOException { 00120 if (bos != null) { 00121 len = bos.size(); 00122 } else if (fos != null) { 00123 fos.close(); 00124 fos = null; 00125 len = (int)file.length(); 00126 } 00127 } 00128 }; 00129 } 00130 00131 public int length() { 00132 return len; 00133 } 00134 00135 static int tmpFileCount = 0; 00136 00137 static synchronized File tmpFile() throws IOException { 00138 return File.createTempFile("" + System.currentTimeMillis() + "." + 00139 (tmpFileCount++), ".tmp"); 00140 } 00141 00142 /** 00143 * Write a byte to the stream. 00144 * 00145 * @param c the byte 00146 * @exception IOException may be thrown 00147 */ 00148 public void doWrite(int c) throws IOException { 00149 if (bos != null) { 00150 if (bos.size() < max) { 00151 bos.write(c); 00152 } else { 00153 file = tmpFile(); 00154 fos = new FileOutputStream(file); 00155 bos.writeTo(fos); 00156 fos.write(c); 00157 bos.close(); 00158 bos = null; 00159 } 00160 } else { 00161 fos.write(c); 00162 } 00163 } 00164 00165 /** 00166 * Return an input stream that the user can use to get his data back 00167 * 00168 * @return the input stream 00169 */ 00170 public InputStream getInputStream() throws IOException { 00171 return getInputStream(true); 00172 } 00173 00174 public InputStream getInputStream(final boolean del) throws IOException { 00175 if (bos != null) return new ByteArrayInputStream(bos.toByteArray()); 00176 if (fos != null) { 00177 fos.close(); 00178 fos = null; 00179 } 00180 if (file != null) { 00181 final FileInputStream fis = new FileInputStream(file); 00182 final File f = file; 00183 if (del) file = null; 00184 return new InputStream() { 00185 public int read() throws IOException { 00186 return fis.read(); 00187 } 00188 public int read(byte[] buf) throws IOException { 00189 return fis.read(buf); 00190 } 00191 public int read(byte[] buf, int off, int cnt) throws IOException { 00192 return fis.read(buf, off, cnt); 00193 } 00194 public void close() throws IOException { 00195 fis.close(); 00196 if (del) f.delete(); 00197 } 00198 public void finalize() { 00199 try { 00200 close(); 00201 } catch (Throwable t) {} 00202 } 00203 }; 00204 } 00205 throw new IOException("no data"); 00206 } 00207 00208 /** 00209 * Return the data as a string 00210 */ 00211 public String toString() { 00212 if (bos != null) return bos.toString(); 00213 if (fos != null) { 00214 throw new RuntimeException("too large"); 00215 } 00216 return null; 00217 } 00218 00219 public void close() { 00220 bos = null; 00221 if (fos != null) { 00222 try { 00223 fos.close(); 00224 } catch (Exception e) { 00225 } 00226 } 00227 fos = null; 00228 if (file != null) { 00229 try { 00230 file.delete(); 00231 } catch (Exception e) { 00232 } 00233 } 00234 file = null; 00235 len = 0; 00236 } 00237 00238 public void reset() { 00239 close(); 00240 } 00241 00242 public void finalize() { 00243 close(); 00244 } 00245 }