View Javadoc
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 }