@@ -62,7 +62,7 @@ public class FileHandle extends AbstractDataHandle<FileLocation> {
62
62
63
63
/** Gets the random access file object backing this FileHandle. */
64
64
public RandomAccessFile getRandomAccessFile () throws IOException {
65
- return raf ();
65
+ return writer ();
66
66
}
67
67
68
68
public String getMode () {
@@ -101,199 +101,199 @@ public Date lastModified() {
101
101
102
102
@ Override
103
103
public long offset () throws IOException {
104
- return raf () .getFilePointer ();
104
+ return exists () ? writer () .getFilePointer () : 0 ;
105
105
}
106
106
107
107
@ Override
108
108
public long length () throws IOException {
109
- return exists () ? raf ().length () : -1 ;
109
+ return exists () ? reader ().length () : -1 ;
110
110
}
111
111
112
112
@ Override
113
113
public void setLength (final long length ) throws IOException {
114
- raf ().setLength (length );
114
+ writer ().setLength (length );
115
115
}
116
116
117
117
@ Override
118
118
public int read () throws IOException {
119
- return raf ().read ();
119
+ return reader ().read ();
120
120
}
121
121
122
122
@ Override
123
123
public int read (final byte [] b ) throws IOException {
124
- return raf ().read (b );
124
+ return reader ().read (b );
125
125
}
126
126
127
127
@ Override
128
128
public int read (final byte [] b , final int off , final int len )
129
129
throws IOException
130
130
{
131
- return raf ().read (b , off , len );
131
+ return reader ().read (b , off , len );
132
132
}
133
133
134
134
@ Override
135
135
public void seek (final long pos ) throws IOException {
136
- raf ().seek (pos );
136
+ reader ().seek (pos );
137
137
}
138
138
139
139
// -- DataInput methods --
140
140
141
141
@ Override
142
142
public boolean readBoolean () throws IOException {
143
- return raf ().readBoolean ();
143
+ return reader ().readBoolean ();
144
144
}
145
145
146
146
@ Override
147
147
public byte readByte () throws IOException {
148
- return raf ().readByte ();
148
+ return reader ().readByte ();
149
149
}
150
150
151
151
@ Override
152
152
public char readChar () throws IOException {
153
- return raf ().readChar ();
153
+ return reader ().readChar ();
154
154
}
155
155
156
156
@ Override
157
157
public double readDouble () throws IOException {
158
- return raf ().readDouble ();
158
+ return reader ().readDouble ();
159
159
}
160
160
161
161
@ Override
162
162
public float readFloat () throws IOException {
163
- return raf ().readFloat ();
163
+ return reader ().readFloat ();
164
164
}
165
165
166
166
@ Override
167
167
public void readFully (final byte [] b ) throws IOException {
168
- raf ().readFully (b );
168
+ reader ().readFully (b );
169
169
}
170
170
171
171
@ Override
172
172
public void readFully (final byte [] b , final int off , final int len )
173
173
throws IOException
174
174
{
175
- raf ().readFully (b , off , len );
175
+ reader ().readFully (b , off , len );
176
176
}
177
177
178
178
@ Override
179
179
public int readInt () throws IOException {
180
- return raf ().readInt ();
180
+ return reader ().readInt ();
181
181
}
182
182
183
183
@ Override
184
184
public String readLine () throws IOException {
185
- return raf ().readLine ();
185
+ return reader ().readLine ();
186
186
}
187
187
188
188
@ Override
189
189
public long readLong () throws IOException {
190
- return raf ().readLong ();
190
+ return reader ().readLong ();
191
191
}
192
192
193
193
@ Override
194
194
public short readShort () throws IOException {
195
- return raf ().readShort ();
195
+ return reader ().readShort ();
196
196
}
197
197
198
198
@ Override
199
199
public int readUnsignedByte () throws IOException {
200
- return raf ().readUnsignedByte ();
200
+ return reader ().readUnsignedByte ();
201
201
}
202
202
203
203
@ Override
204
204
public int readUnsignedShort () throws IOException {
205
- return raf ().readUnsignedShort ();
205
+ return reader ().readUnsignedShort ();
206
206
}
207
207
208
208
@ Override
209
209
public String readUTF () throws IOException {
210
- return raf ().readUTF ();
210
+ return reader ().readUTF ();
211
211
}
212
212
213
213
@ Override
214
214
public int skipBytes (final int n ) throws IOException {
215
- return raf ().skipBytes (n );
215
+ return reader ().skipBytes (n );
216
216
}
217
217
218
218
// -- DataOutput methods --
219
219
220
220
@ Override
221
221
public void write (final byte [] b ) throws IOException {
222
- raf ().write (b );
222
+ writer ().write (b );
223
223
}
224
224
225
225
@ Override
226
226
public void write (final byte [] b , final int off , final int len )
227
227
throws IOException
228
228
{
229
- raf ().write (b , off , len );
229
+ writer ().write (b , off , len );
230
230
}
231
231
232
232
@ Override
233
233
public void write (final int b ) throws IOException {
234
- raf ().write (b );
234
+ writer ().write (b );
235
235
}
236
236
237
237
@ Override
238
238
public void writeBoolean (final boolean v ) throws IOException {
239
- raf ().writeBoolean (v );
239
+ writer ().writeBoolean (v );
240
240
}
241
241
242
242
@ Override
243
243
public void writeByte (final int v ) throws IOException {
244
- raf ().writeByte (v );
244
+ writer ().writeByte (v );
245
245
}
246
246
247
247
@ Override
248
248
public void writeBytes (final String s ) throws IOException {
249
- raf ().writeBytes (s );
249
+ writer ().writeBytes (s );
250
250
}
251
251
252
252
@ Override
253
253
public void writeChar (final int v ) throws IOException {
254
- raf ().writeChar (v );
254
+ writer ().writeChar (v );
255
255
}
256
256
257
257
@ Override
258
258
public void writeChars (final String s ) throws IOException {
259
- raf ().writeChars (s );
259
+ writer ().writeChars (s );
260
260
}
261
261
262
262
@ Override
263
263
public void writeDouble (final double v ) throws IOException {
264
- raf ().writeDouble (v );
264
+ writer ().writeDouble (v );
265
265
}
266
266
267
267
@ Override
268
268
public void writeFloat (final float v ) throws IOException {
269
- raf ().writeFloat (v );
269
+ writer ().writeFloat (v );
270
270
}
271
271
272
272
@ Override
273
273
public void writeInt (final int v ) throws IOException {
274
- raf ().writeInt (v );
274
+ writer ().writeInt (v );
275
275
}
276
276
277
277
@ Override
278
278
public void writeLong (final long v ) throws IOException {
279
- raf ().writeLong (v );
279
+ writer ().writeLong (v );
280
280
}
281
281
282
282
@ Override
283
283
public void writeShort (final int v ) throws IOException {
284
- raf ().writeShort (v );
284
+ writer ().writeShort (v );
285
285
}
286
286
287
287
@ Override
288
288
public void writeUTF (final String str ) throws IOException {
289
- raf ().writeUTF (str );
289
+ writer ().writeUTF (str );
290
290
}
291
291
292
292
// -- Closeable methods --
293
293
294
294
@ Override
295
295
public synchronized void close () throws IOException {
296
- if (raf != null ) raf () .close ();
296
+ if (raf != null ) raf .close ();
297
297
closed = true ;
298
298
}
299
299
@@ -306,12 +306,46 @@ public Class<FileLocation> getType() {
306
306
307
307
// -- Helper methods --
308
308
309
- private RandomAccessFile raf () throws IOException {
310
- if (raf == null ) initRAF ();
309
+ /**
310
+ * Access method for the internal {@link RandomAccessFile}, that succeeds
311
+ * independently of the underlying file existing on disk. This allows us to
312
+ * create a new file for writing.
313
+ *
314
+ * @return the internal {@link RandomAccessFile} or creates if if needed.
315
+ * @throws IOException if the {@link RandomAccessFile} could not be created.
316
+ */
317
+ private RandomAccessFile writer () throws IOException {
318
+ if (raf == null ) initRAF (true );
311
319
return raf ;
312
320
}
313
321
314
- private synchronized void initRAF () throws IOException {
322
+ /**
323
+ * Access method for the internal {@link RandomAccessFile}, that only succeeds
324
+ * if the underlying file exists on disk. This prevents accidental creation of
325
+ * an empty RAF file when calling read operations on a non-existent file.
326
+ *
327
+ * @return the internal {@link RandomAccessFile} or creates if if needed.
328
+ * @throws IOException if the {@link RandomAccessFile} could not be created,
329
+ * or the backing file does not exists.
330
+ */
331
+ private RandomAccessFile reader () throws IOException {
332
+ if (raf == null ) initRAF (false );
333
+ return raf ;
334
+ }
335
+
336
+ /**
337
+ * Initializes the {@link RandomAccessFile},
338
+ *
339
+ * @param create whether to create the {@link RandomAccessFile} if the
340
+ * underlying file does not exist yet.
341
+ * @throws IOException if the {@link RandomAccessFile} could not be created,
342
+ * or the backing file does not exists and the {@code create}
343
+ * parameter was set to {@code true}.
344
+ */
345
+ private synchronized void initRAF (final boolean create ) throws IOException {
346
+ if (!create && !exists ()) {
347
+ throw new IOException ("Trying to read from non-existent file!" );
348
+ }
315
349
if (closed ) throw new IOException ("Handle already closed" );
316
350
if (raf != null ) return ;
317
351
raf = new RandomAccessFile (get ().getFile (), getMode ());
0 commit comments