Skip to content

Commit ceb430f

Browse files
committed
Fix #329: Don't create empty RAF files on reading
When trying to read from a non-existing file, the FileHandle created a RandomAccessFile, which resulted in an empty file appearing on disk.
1 parent 2bd4dc8 commit ceb430f

File tree

1 file changed

+66
-39
lines changed

1 file changed

+66
-39
lines changed

src/main/java/org/scijava/io/handle/FileHandle.java

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public class FileHandle extends AbstractDataHandle<FileLocation> {
6262

6363
/** Gets the random access file object backing this FileHandle. */
6464
public RandomAccessFile getRandomAccessFile() throws IOException {
65-
return raf();
65+
return writeRaf();
6666
}
6767

6868
public String getMode() {
@@ -101,199 +101,199 @@ public Date lastModified() {
101101

102102
@Override
103103
public long offset() throws IOException {
104-
return raf().getFilePointer();
104+
return exists() ? writeRaf().getFilePointer() : 0;
105105
}
106106

107107
@Override
108108
public long length() throws IOException {
109-
return exists() ? raf().length() : -1;
109+
return exists() ? writeRaf().length() : -1;
110110
}
111111

112112
@Override
113113
public void setLength(final long length) throws IOException {
114-
raf().setLength(length);
114+
writeRaf().setLength(length);
115115
}
116116

117117
@Override
118118
public int read() throws IOException {
119-
return raf().read();
119+
return readRaf().read();
120120
}
121121

122122
@Override
123123
public int read(final byte[] b) throws IOException {
124-
return raf().read(b);
124+
return readRaf().read(b);
125125
}
126126

127127
@Override
128128
public int read(final byte[] b, final int off, final int len)
129129
throws IOException
130130
{
131-
return raf().read(b, off, len);
131+
return readRaf().read(b, off, len);
132132
}
133133

134134
@Override
135135
public void seek(final long pos) throws IOException {
136-
raf().seek(pos);
136+
readRaf().seek(pos);
137137
}
138138

139139
// -- DataInput methods --
140140

141141
@Override
142142
public boolean readBoolean() throws IOException {
143-
return raf().readBoolean();
143+
return readRaf().readBoolean();
144144
}
145145

146146
@Override
147147
public byte readByte() throws IOException {
148-
return raf().readByte();
148+
return readRaf().readByte();
149149
}
150150

151151
@Override
152152
public char readChar() throws IOException {
153-
return raf().readChar();
153+
return readRaf().readChar();
154154
}
155155

156156
@Override
157157
public double readDouble() throws IOException {
158-
return raf().readDouble();
158+
return readRaf().readDouble();
159159
}
160160

161161
@Override
162162
public float readFloat() throws IOException {
163-
return raf().readFloat();
163+
return readRaf().readFloat();
164164
}
165165

166166
@Override
167167
public void readFully(final byte[] b) throws IOException {
168-
raf().readFully(b);
168+
readRaf().readFully(b);
169169
}
170170

171171
@Override
172172
public void readFully(final byte[] b, final int off, final int len)
173173
throws IOException
174174
{
175-
raf().readFully(b, off, len);
175+
readRaf().readFully(b, off, len);
176176
}
177177

178178
@Override
179179
public int readInt() throws IOException {
180-
return raf().readInt();
180+
return readRaf().readInt();
181181
}
182182

183183
@Override
184184
public String readLine() throws IOException {
185-
return raf().readLine();
185+
return readRaf().readLine();
186186
}
187187

188188
@Override
189189
public long readLong() throws IOException {
190-
return raf().readLong();
190+
return readRaf().readLong();
191191
}
192192

193193
@Override
194194
public short readShort() throws IOException {
195-
return raf().readShort();
195+
return readRaf().readShort();
196196
}
197197

198198
@Override
199199
public int readUnsignedByte() throws IOException {
200-
return raf().readUnsignedByte();
200+
return readRaf().readUnsignedByte();
201201
}
202202

203203
@Override
204204
public int readUnsignedShort() throws IOException {
205-
return raf().readUnsignedShort();
205+
return readRaf().readUnsignedShort();
206206
}
207207

208208
@Override
209209
public String readUTF() throws IOException {
210-
return raf().readUTF();
210+
return readRaf().readUTF();
211211
}
212212

213213
@Override
214214
public int skipBytes(final int n) throws IOException {
215-
return raf().skipBytes(n);
215+
return readRaf().skipBytes(n);
216216
}
217217

218218
// -- DataOutput methods --
219219

220220
@Override
221221
public void write(final byte[] b) throws IOException {
222-
raf().write(b);
222+
writeRaf().write(b);
223223
}
224224

225225
@Override
226226
public void write(final byte[] b, final int off, final int len)
227227
throws IOException
228228
{
229-
raf().write(b, off, len);
229+
writeRaf().write(b, off, len);
230230
}
231231

232232
@Override
233233
public void write(final int b) throws IOException {
234-
raf().write(b);
234+
writeRaf().write(b);
235235
}
236236

237237
@Override
238238
public void writeBoolean(final boolean v) throws IOException {
239-
raf().writeBoolean(v);
239+
writeRaf().writeBoolean(v);
240240
}
241241

242242
@Override
243243
public void writeByte(final int v) throws IOException {
244-
raf().writeByte(v);
244+
writeRaf().writeByte(v);
245245
}
246246

247247
@Override
248248
public void writeBytes(final String s) throws IOException {
249-
raf().writeBytes(s);
249+
writeRaf().writeBytes(s);
250250
}
251251

252252
@Override
253253
public void writeChar(final int v) throws IOException {
254-
raf().writeChar(v);
254+
writeRaf().writeChar(v);
255255
}
256256

257257
@Override
258258
public void writeChars(final String s) throws IOException {
259-
raf().writeChars(s);
259+
writeRaf().writeChars(s);
260260
}
261261

262262
@Override
263263
public void writeDouble(final double v) throws IOException {
264-
raf().writeDouble(v);
264+
writeRaf().writeDouble(v);
265265
}
266266

267267
@Override
268268
public void writeFloat(final float v) throws IOException {
269-
raf().writeFloat(v);
269+
writeRaf().writeFloat(v);
270270
}
271271

272272
@Override
273273
public void writeInt(final int v) throws IOException {
274-
raf().writeInt(v);
274+
writeRaf().writeInt(v);
275275
}
276276

277277
@Override
278278
public void writeLong(final long v) throws IOException {
279-
raf().writeLong(v);
279+
writeRaf().writeLong(v);
280280
}
281281

282282
@Override
283283
public void writeShort(final int v) throws IOException {
284-
raf().writeShort(v);
284+
writeRaf().writeShort(v);
285285
}
286286

287287
@Override
288288
public void writeUTF(final String str) throws IOException {
289-
raf().writeUTF(str);
289+
writeRaf().writeUTF(str);
290290
}
291291

292292
// -- Closeable methods --
293293

294294
@Override
295295
public synchronized void close() throws IOException {
296-
if (raf != null) raf().close();
296+
if (raf != null) raf.close();
297297
closed = true;
298298
}
299299

@@ -306,11 +306,38 @@ public Class<FileLocation> getType() {
306306

307307
// -- Helper methods --
308308

309-
private RandomAccessFile raf() throws IOException {
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 files 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 writeRaf() throws IOException {
310318
if (raf == null) initRAF();
311319
return raf;
312320
}
313321

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+
* 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 readRaf() throws IOException {
332+
if (raf == null) {
333+
if (!exists()) {
334+
throw new IOException("Trying to read from non-existent file!");
335+
}
336+
initRAF();
337+
}
338+
return raf;
339+
}
340+
314341
private synchronized void initRAF() throws IOException {
315342
if (closed) throw new IOException("Handle already closed");
316343
if (raf != null) return;

0 commit comments

Comments
 (0)