1 package de.japrost.jabudget.serialization; 2 3 import java.io.File; 4 import java.io.FileDescriptor; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.OutputStream; 9 import java.nio.channels.FileChannel; 10 11 /** 12 * An {@link OutputStream} that uses a {@link FileOutputStream} internally, which is created when first access is done. 13 * On {@link OutputStream#close()} the internal {@link FileOutputStream} will be closed and unset that next writing will 14 * get a new stream. 15 */ 16 //TODO move to a io project 17 public class LazyFileOutputStream extends OutputStream { 18 19 private final File file; 20 private FileOutputStream delegate; 21 22 /** 23 * Create an instance based on the given File. 24 * 25 * @param file the file to use in the internal delegate. 26 */ 27 public LazyFileOutputStream(final File file) { 28 // TODO require non null 29 this.file = file; 30 } 31 32 /** 33 * {@inheritDoc} 34 * <p> 35 * <strong>This implementation</strong> calls {@link FileOutputStream#close()} on the delegate and unassigns the 36 * delegate. 37 */ 38 @Override 39 public void close() throws IOException { 40 if (delegate != null) { 41 delegate.close(); 42 delegate = null; 43 } 44 } 45 46 /** 47 * {@inheritDoc} 48 * <p> 49 * <strong>This implementation</strong> calls {@link FileOutputStream#flush()} on the delegate if it is initalized. 50 */ 51 @Override 52 public void flush() throws IOException { 53 if (delegate != null) { 54 delegate.flush(); 55 } 56 } 57 58 /** 59 * Initializes the delegate if not already done and delegates to {@link FileOutputStream#getChannel()}. 60 * 61 * @return {@link FileOutputStream#getChannel()} 62 * @throws FileNotFoundException if initialization of delegate fails. see 63 * {@link FileOutputStream#FileOutputStream(File)}. 64 */ 65 public FileChannel getChannel() throws FileNotFoundException { 66 if (delegate == null) { 67 initDelegate(); 68 } 69 return delegate.getChannel(); 70 } 71 72 /** 73 * Initializes the delegate if not already done and delegates to {@link FileOutputStream#getFD()}. 74 * 75 * @return {@link FileOutputStream#getFD()} 76 * @throws IOException see {@link FileOutputStream#getFD()}. 77 * @throws FileNotFoundException if initialization of delegate fails. see 78 * {@link FileOutputStream#FileOutputStream(File)}. 79 */ 80 public FileDescriptor getFD() throws IOException { 81 if (delegate == null) { 82 initDelegate(); 83 } 84 return delegate.getFD(); 85 } 86 87 /** 88 * {@inheritDoc} 89 * <p> 90 * <strong>This implementation</strong> innitializes the delegate if not already done and delegates to 91 * {@link FileOutputStream#write(byte[])}. 92 * 93 * @throws FileNotFoundException if initialization of delegate fails. see 94 * {@link FileOutputStream#FileOutputStream(File)}. 95 */ 96 @Override 97 public void write(final byte[] b) throws IOException { 98 if (delegate == null) { 99 initDelegate(); 100 } 101 delegate.write(b); 102 } 103 104 /** 105 * {@inheritDoc} 106 * <p> 107 * <strong>This implementation</strong> innitializes the delegate if not already done and delegates to 108 * {@link FileOutputStream#write(byte[], int, int)}. 109 * 110 * @throws FileNotFoundException if initialization of delegate fails. see 111 * {@link FileOutputStream#FileOutputStream(File)}. 112 */ 113 @Override 114 public void write(final byte[] b, final int off, final int len) throws IOException { 115 if (delegate == null) { 116 initDelegate(); 117 } 118 delegate.write(b, off, len); 119 } 120 121 /** 122 * {@inheritDoc} 123 * <p> 124 * <strong>This implementation</strong> innitializes the delegate if not already done and delegates to 125 * {@link FileOutputStream#write(int)}. 126 * 127 * @throws FileNotFoundException if initialization of delegate fails. see 128 * {@link FileOutputStream#FileOutputStream(File)}. 129 */ 130 @Override 131 public void write(final int b) throws IOException { 132 if (delegate == null) { 133 initDelegate(); 134 } 135 delegate.write(b); 136 } 137 138 /** 139 * Tell if the delegate is initialized. 140 * 141 * @return {@code true} if there is a delegate. 142 */ 143 public boolean isOpen() { 144 return delegate != null; 145 } 146 147 private void initDelegate() throws FileNotFoundException { 148 delegate = new FileOutputStream(file); 149 } 150 151 }