1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jdtaus.core.io.util;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.io.RandomAccessFile;
27 import java.util.Locale;
28 import org.jdtaus.core.container.ContainerFactory;
29 import org.jdtaus.core.io.FileOperations;
30 import org.jdtaus.core.lang.spi.MemoryManager;
31
32
33
34
35
36
37
38 public final class RandomAccessFileOperations implements FileOperations
39 {
40
41
42
43
44
45
46
47
48
49
50 private MemoryManager getMemoryManager()
51 {
52 return (MemoryManager) ContainerFactory.getContainer().
53 getDependency( this, "MemoryManager" );
54
55 }
56
57
58
59
60
61
62 private Locale getLocale()
63 {
64 return (Locale) ContainerFactory.getContainer().
65 getDependency( this, "Locale" );
66
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 private int getStreamBufferSize()
83 {
84 return ( (java.lang.Integer) ContainerFactory.getContainer().
85 getProperty( this, "streamBufferSize" ) ).intValue();
86
87 }
88
89
90
91
92
93
94
95 private transient long cachedLength = NO_CACHEDLENGTH;
96
97 private static final long NO_CACHEDLENGTH = Long.MIN_VALUE;
98
99 public long getLength() throws IOException
100 {
101 this.assertNotClosed();
102
103 return this.cachedLength != NO_CACHEDLENGTH
104 ? this.cachedLength
105 : ( this.cachedLength =
106 this.getRandomAccessFile().length() );
107
108 }
109
110 public void setLength( final long newLength ) throws IOException
111 {
112 if ( newLength < 0L )
113 {
114 throw new IllegalArgumentException( Long.toString( newLength ) );
115 }
116
117 this.assertNotClosed();
118
119 this.getRandomAccessFile().setLength( newLength );
120 this.cachedLength = newLength;
121 }
122
123 public long getFilePointer() throws IOException
124 {
125 this.assertNotClosed();
126
127 return this.getRandomAccessFile().getFilePointer();
128 }
129
130 public void setFilePointer( final long pos ) throws IOException
131 {
132 this.assertNotClosed();
133
134 this.getRandomAccessFile().seek( pos );
135 }
136
137 public void write( final byte[] buf, final int off, final int len )
138 throws IOException
139 {
140 this.assertNotClosed();
141
142 final RandomAccessFile file = this.getRandomAccessFile();
143 final long pointer = file.getFilePointer();
144
145 file.write( buf, off, len );
146
147 if ( this.cachedLength != NO_CACHEDLENGTH &&
148 pointer + len > this.cachedLength )
149 {
150 this.cachedLength = file.length();
151 }
152 }
153
154 public int read( final byte[] buf, final int off, final int len )
155 throws IOException
156 {
157 this.assertNotClosed();
158
159 return this.getRandomAccessFile().read( buf, off, len );
160 }
161
162 public void read( final OutputStream out ) throws IOException
163 {
164 if ( out == null )
165 {
166 throw new NullPointerException( "out" );
167 }
168
169 this.assertNotClosed();
170
171 int read;
172 long toRead = this.getLength();
173 final byte[] buf = this.getStreamBuffer();
174
175 if ( toRead > 0L )
176 {
177 this.setFilePointer( 0L );
178 do
179 {
180 read = this.read( buf, 0, buf.length );
181
182 assert read != FileOperations.EOF : "Unexpected end of file.";
183
184 toRead -= read;
185 out.write( buf, 0, read );
186 }
187 while ( toRead > 0L );
188 }
189 }
190
191 public void write( final InputStream in ) throws IOException
192 {
193 if ( in == null )
194 {
195 throw new NullPointerException( "in" );
196 }
197
198 this.assertNotClosed();
199
200 int read;
201 final byte[] buf = this.getStreamBuffer();
202
203 while ( ( read = in.read( buf, 0, buf.length ) ) != FileOperations.EOF )
204 {
205 this.write( buf, 0, read );
206 }
207 }
208
209
210
211
212
213
214
215
216 public void close() throws IOException
217 {
218 this.assertNotClosed();
219
220 this.getRandomAccessFile().close();
221 this.closed = true;
222 }
223
224
225
226
227
228 private byte[] streamBuffer;
229
230
231 private boolean closed;
232
233
234 private RandomAccessFile randomAccessFile;
235
236
237
238
239
240
241
242
243
244
245 public RandomAccessFileOperations( final RandomAccessFile file )
246 {
247 super();
248
249 if ( file == null )
250 {
251 throw new NullPointerException( "file" );
252 }
253
254 this.randomAccessFile = file;
255 }
256
257
258
259
260
261
262
263 public RandomAccessFile getRandomAccessFile()
264 {
265 return this.randomAccessFile;
266 }
267
268
269
270
271
272
273 private void assertNotClosed() throws IOException
274 {
275 if ( this.closed )
276 {
277 throw new IOException( this.getAlreadyClosedMessage(
278 this.getLocale() ) );
279
280 }
281 }
282
283
284
285
286
287
288 private byte[] getStreamBuffer()
289 {
290 if ( this.streamBuffer == null )
291 {
292 this.streamBuffer = this.getMemoryManager().
293 allocateBytes( this.getStreamBufferSize() < 0
294 ? 0
295 : this.getStreamBufferSize() );
296
297 }
298
299 return this.streamBuffer;
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 private String getAlreadyClosedMessage( final Locale locale )
318 {
319 return ContainerFactory.getContainer().
320 getMessage( this, "alreadyClosed", locale, null );
321
322 }
323
324
325
326
327 }