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( 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( long pos ) throws IOException
131 {
132 this.assertNotClosed();
133
134 this.getRandomAccessFile().seek( pos );
135 }
136
137 public void write( byte[] buf, int off, int len ) throws IOException
138 {
139 this.assertNotClosed();
140
141 final RandomAccessFile file = this.getRandomAccessFile();
142 final long pointer = file.getFilePointer();
143
144 file.write( buf, off, len );
145
146 if ( this.cachedLength != NO_CACHEDLENGTH &&
147 pointer + len > this.cachedLength )
148 {
149 this.cachedLength = file.length();
150 }
151 }
152
153 public int read( byte[] buf, int off, int len ) throws IOException
154 {
155 this.assertNotClosed();
156
157 return this.getRandomAccessFile().read( buf, off, len );
158 }
159
160 public void read( final OutputStream out ) throws IOException
161 {
162 if ( out == null )
163 {
164 throw new NullPointerException( "out" );
165 }
166
167 this.assertNotClosed();
168
169 int read;
170 long toRead = this.getLength();
171 final byte[] buf = this.getStreamBuffer();
172
173 if ( toRead > 0L )
174 {
175 this.setFilePointer( 0L );
176 do
177 {
178 read = this.read( buf, 0, buf.length );
179
180 assert read != FileOperations.EOF : "Unexpected end of file.";
181
182 toRead -= read;
183 out.write( buf, 0, read );
184 }
185 while ( toRead > 0L );
186 }
187 }
188
189 public void write( final InputStream in ) throws IOException
190 {
191 if ( in == null )
192 {
193 throw new NullPointerException( "in" );
194 }
195
196 this.assertNotClosed();
197
198 int read;
199 final byte[] buf = this.getStreamBuffer();
200
201 while ( ( read = in.read( buf, 0, buf.length ) ) != FileOperations.EOF )
202 {
203 this.write( buf, 0, read );
204 }
205 }
206
207
208
209
210
211
212
213
214 public void close() throws IOException
215 {
216 this.assertNotClosed();
217
218 this.getRandomAccessFile().close();
219 this.closed = true;
220 }
221
222
223
224
225
226 private byte[] streamBuffer;
227
228
229 private boolean closed;
230
231
232 private RandomAccessFile randomAccessFile;
233
234
235
236
237
238
239
240
241
242
243 public RandomAccessFileOperations( final RandomAccessFile file )
244 {
245 super();
246
247 if ( file == null )
248 {
249 throw new NullPointerException( "file" );
250 }
251
252 this.randomAccessFile = file;
253 }
254
255
256
257
258
259
260
261 public RandomAccessFile getRandomAccessFile()
262 {
263 return this.randomAccessFile;
264 }
265
266
267
268
269
270
271 private void assertNotClosed() throws IOException
272 {
273 if ( this.closed )
274 {
275 throw new IOException( this.getAlreadyClosedMessage(
276 this.getLocale() ) );
277
278 }
279 }
280
281
282
283
284
285
286 private byte[] getStreamBuffer()
287 {
288 if ( this.streamBuffer == null )
289 {
290 this.streamBuffer = this.getMemoryManager().
291 allocateBytes( this.getStreamBufferSize() < 0
292 ? 0
293 : this.getStreamBufferSize() );
294
295 }
296
297 return this.streamBuffer;
298 }
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315 private String getAlreadyClosedMessage( final Locale locale )
316 {
317 return ContainerFactory.getContainer().
318 getMessage( this, "alreadyClosed", locale, null );
319
320 }
321
322
323
324
325 }