1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package uk.ac.rdg.resc.jstyx.client;
30
31 import java.io.OutputStream;
32 import java.io.IOException;
33
34 import uk.ac.rdg.resc.jstyx.StyxUtils;
35 import uk.ac.rdg.resc.jstyx.StyxException;
36
37 /***
38 * Output stream for writing data to a Styx File. The file will be truncated
39 * at the end of the data that are written through this class.
40 *
41 * @author Jon Blower
42 * $Revision: 507 $
43 * $Date: 2005-12-01 08:21:56 +0000 (Thu, 01 Dec 2005) $
44 * $Log$
45 * Revision 1.4 2005/12/01 08:21:55 jonblower
46 * Fixed javadoc comments
47 *
48 * Revision 1.3 2005/10/14 18:04:33 jonblower
49 * Fixed bug with not updating file offset, and added code to write zero bytes to signify EOF
50 *
51 * Revision 1.2 2005/09/01 17:12:10 jonblower
52 * Changes to Input and Output stream code
53 *
54 * Revision 1.1 2005/08/31 17:03:18 jonblower
55 * Renamed "StyxFile*putStream*" to "CStyxFile*putStream*" for consistency with CStyxFile class
56 *
57 * Revision 1.4 2005/05/23 16:48:17 jonblower
58 * Overhauled CStyxFile (esp. asynchronous methods) and StyxConnection (added cache of CStyxFiles)
59 *
60 * Revision 1.3 2005/05/12 07:40:52 jonblower
61 * CStyxFile.close() no longer throws a StyxException
62 *
63 * Revision 1.2 2005/03/16 17:55:53 jonblower
64 * Replaced use of java.nio.ByteBuffer with MINA's ByteBuffer to minimise copying of buffers
65 *
66 * Revision 1.1.1.1 2005/02/16 18:58:19 jonblower
67 * Initial import
68 */
69 public class CStyxFileOutputStream extends OutputStream
70 {
71
72 private CStyxFile file;
73 private byte[] buf;
74 private int pos;
75 private long offset;
76 private boolean closeConnectionWhenCloseStream;
77
78
79
80 /***
81 * Creates a new CStyxFileOutputStream to write data to the given CStyxFile.
82 * If the file already exists it will be overwritten.
83 * @param file the file to write to
84 * @param closeConnectionWhenCloseStream If this is true, we shall close the underlying
85 * StyxConnection when this stream is closed (this is normally set when
86 * getting an output stream through the StyxURLConnection class)
87 * @todo Add flag to prevent overwriting in certain cases?
88 */
89 public CStyxFileOutputStream(CStyxFile file, boolean closeConnectionWhenCloseStream) throws StyxException
90 {
91 if (file == null)
92 {
93 throw new NullPointerException("file cannot be null");
94 }
95 this.file = file;
96 this.file.openOrCreate(false, StyxUtils.OWRITE | StyxUtils.OTRUNC);
97 this.buf = new byte[(int)this.file.getIoUnit()];
98 this.pos = 0;
99 this.offset = 0;
100 this.closeConnectionWhenCloseStream = closeConnectionWhenCloseStream;
101 }
102
103 /***
104 * Creates a new CStyxFileOutputStream to write data to the given CStyxFile.
105 * If the file already exists it will be overwritten.
106 * @todo Add flag to prevent overwriting in certain cases?
107 */
108 public CStyxFileOutputStream(CStyxFile file) throws StyxException
109 {
110 this(file, false);
111 }
112
113 /***
114 * Writes the specified byte to the Styx file. Must call flush() to
115 * guarantee that the byte is actually written, as it may be held in a
116 * buffer.
117 */
118 public synchronized void write(int b) throws IOException
119 {
120
121 this.buf[this.pos] = (byte)b;
122 this.pos++;
123
124 if (this.pos >= this.buf.length)
125 {
126 this.flush();
127 }
128 }
129
130 /***
131 * Flushes the internal buffer and forces any buffered output bytes to be
132 * written
133 */
134 public synchronized void flush() throws IOException
135 {
136
137 try
138 {
139 this.file.write(this.buf, 0, pos, this.offset, true);
140
141 this.offset += pos;
142
143 this.pos = 0;
144 }
145 catch(StyxException se)
146 {
147 throw new IOException(se.getMessage());
148 }
149 }
150
151 /***
152 * Closes the file stream (i.e. clunks the fid of the underlying file) and
153 * flushes any remaining data to the file.
154 */
155 public synchronized void close() throws IOException
156 {
157
158 this.flush();
159
160
161 this.flush();
162
163 this.file.close();
164 if (this.closeConnectionWhenCloseStream)
165 {
166 this.file.getConnection().close();
167 }
168 }
169 }