Skip to content

Commit f227ffa

Browse files
authored
Merge pull request #155 from saalfeldlab/readDataN5IOExceptions
Migrate IOExceptions to N5IOExceptions for ReadData and related logic
2 parents 358e61a + 1ae6ded commit f227ffa

26 files changed

Lines changed: 419 additions & 329 deletions

src/main/java/org/janelia/saalfeldlab/n5/Bzip2Compression.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
* %%
77
* Redistribution and use in source and binary forms, with or without
88
* modification, are permitted provided that the following conditions are met:
9-
*
9+
*
1010
* 1. Redistributions of source code must retain the above copyright notice,
1111
* this list of conditions and the following disclaimer.
1212
* 2. Redistributions in binary form must reproduce the above copyright notice,
1313
* this list of conditions and the following disclaimer in the documentation
1414
* and/or other materials provided with the distribution.
15-
*
15+
*
1616
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1717
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1818
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -58,6 +58,7 @@
5858
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
5959
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
6060
import org.janelia.saalfeldlab.n5.Compression.CompressionType;
61+
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
6162
import org.janelia.saalfeldlab.n5.readdata.ReadData;
6263

6364
@CompressionType("bzip2")
@@ -88,9 +89,12 @@ public boolean equals(final Object other) {
8889
}
8990

9091
@Override
91-
public ReadData decode(final ReadData readData) throws IOException {
92-
93-
return ReadData.from(new BZip2CompressorInputStream(readData.inputStream()));
92+
public ReadData decode(final ReadData readData) throws N5IOException {
93+
try {
94+
return ReadData.from(new BZip2CompressorInputStream(readData.inputStream()));
95+
} catch (IOException e) {
96+
throw new N5IOException(e);
97+
}
9498
}
9599

96100
@Override

src/main/java/org/janelia/saalfeldlab/n5/CachedGsonKeyValueN5Writer.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,7 @@ else if (getCache().exists(normalPath, N5KeyValueReader.ATTRIBUTES_JSON)) {
7474
* the lines below duplicate the single line above but would have to call
7575
* normalizeGroupPath again the below duplicates code, but avoids extra work
7676
*/
77-
try {
78-
getKeyValueAccess().createDirectories(absoluteGroupPath(normalPath));
79-
} catch (final IOException | UncheckedIOException e) {
80-
throw new N5Exception.N5IOException("Failed to create group " + path, e);
81-
}
77+
getKeyValueAccess().createDirectories(absoluteGroupPath(normalPath));
8278

8379
if (cacheMeta()) {
8480
// check all nodes that are parents of the added node, if they have
@@ -148,12 +144,9 @@ default boolean remove(final String path) throws N5Exception {
148144
*/
149145
final String normalPath = N5URI.normalizeGroupPath(path);
150146
final String groupPath = absoluteGroupPath(normalPath);
151-
try {
152-
if (getKeyValueAccess().isDirectory(groupPath))
153-
getKeyValueAccess().delete(groupPath);
154-
} catch (final IOException | UncheckedIOException e) {
155-
throw new N5IOException("Failed to remove " + path, e);
156-
}
147+
148+
if (getKeyValueAccess().isDirectory(groupPath))
149+
getKeyValueAccess().delete(groupPath);
157150

158151
if (cacheMeta()) {
159152
final String parentPath = getKeyValueAccess().parent(normalPath);

src/main/java/org/janelia/saalfeldlab/n5/Compression.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
* %%
77
* Redistribution and use in source and binary forms, with or without
88
* modification, are permitted provided that the following conditions are met:
9-
*
9+
*
1010
* 1. Redistributions of source code must retain the above copyright notice,
1111
* this list of conditions and the following disclaimer.
1212
* 2. Redistributions in binary form must reproduce the above copyright notice,
1313
* this list of conditions and the following disclaimer in the documentation
1414
* and/or other materials provided with the distribution.
15-
*
15+
*
1616
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1717
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1818
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -60,6 +60,8 @@
6060
import java.lang.annotation.Retention;
6161
import java.lang.annotation.RetentionPolicy;
6262
import java.lang.annotation.Target;
63+
64+
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
6365
import org.janelia.saalfeldlab.n5.readdata.ReadData;
6466
import org.scijava.annotations.Indexable;
6567

@@ -116,10 +118,10 @@ default String getType() {
116118
*
117119
* @return decoded ReadData
118120
*
119-
* @throws IOException
121+
* @throws N5IOException
120122
* if any I/O error occurs
121123
*/
122-
ReadData decode(ReadData readData) throws IOException;
124+
ReadData decode(ReadData readData) throws N5IOException;
123125

124126
/**
125127
* Encode the given {@code readData}.
@@ -132,9 +134,9 @@ default String getType() {
132134
*
133135
* @return encoded ReadData
134136
*
135-
* @throws IOException
137+
* @throws N5IOException
136138
* if any I/O error occurs
137139
*/
138-
ReadData encode(ReadData readData) throws IOException;
140+
ReadData encode(ReadData readData) throws N5IOException;
139141

140142
}

src/main/java/org/janelia/saalfeldlab/n5/DefaultBlockReader.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555

5656
import java.io.IOException;
5757
import java.io.InputStream;
58+
59+
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
5860
import org.janelia.saalfeldlab.n5.codec.DataBlockCodec;
5961
import org.janelia.saalfeldlab.n5.readdata.ReadData;
6062

@@ -76,13 +78,13 @@ public interface DefaultBlockReader {
7678
* @param gridPosition
7779
* the grid position
7880
* @return the block
79-
* @throws IOException
81+
* @throws N5IOException
8082
* the exception
8183
*/
8284
static DataBlock<?> readBlock(
8385
final InputStream in,
8486
final DatasetAttributes datasetAttributes,
85-
final long[] gridPosition) throws IOException {
87+
final long[] gridPosition) throws N5IOException {
8688

8789
final DataBlockCodec<?> codec = datasetAttributes.getDataBlockCodec();
8890
return codec.decode(ReadData.from(in), gridPosition);

src/main/java/org/janelia/saalfeldlab/n5/DefaultBlockWriter.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555

5656
import java.io.IOException;
5757
import java.io.OutputStream;
58+
59+
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
5860
import org.janelia.saalfeldlab.n5.codec.DataBlockCodec;
5961

6062
/**
@@ -75,13 +77,13 @@ public interface DefaultBlockWriter {
7577
* the dataset attributes
7678
* @param dataBlock
7779
* the data block the block data type
78-
* @throws IOException
80+
* @throws N5IOException
7981
* the exception
8082
*/
8183
static <T> void writeBlock(
8284
final OutputStream out,
8385
final DatasetAttributes datasetAttributes,
84-
final DataBlock<T> dataBlock) throws IOException {
86+
final DataBlock<T> dataBlock) throws N5IOException {
8587

8688
final DataBlockCodec<T> codec = datasetAttributes.getDataBlockCodec();
8789
codec.encode(dataBlock).writeTo(out);

src/main/java/org/janelia/saalfeldlab/n5/FileSystemKeyValueAccess.java

Lines changed: 85 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,15 @@
5353
*/
5454
package org.janelia.saalfeldlab.n5;
5555

56+
import org.janelia.saalfeldlab.n5.N5Exception.N5IOException;
57+
import org.janelia.saalfeldlab.n5.N5Exception.N5NoSuchKeyException;
58+
5659
import java.io.File;
5760
import java.io.IOException;
5861
import java.io.InputStream;
5962
import java.io.OutputStream;
6063
import java.io.Reader;
64+
import java.io.UncheckedIOException;
6165
import java.io.Writer;
6266
import java.net.URI;
6367
import java.net.URISyntaxException;
@@ -141,29 +145,40 @@ protected LockedFileChannel(final Path path, final boolean readOnly) throws IOEx
141145
}
142146
}
143147

148+
private void truncateChannel(int size) {
149+
150+
try {
151+
channel.truncate(size);
152+
} catch (NoSuchFileException e) {
153+
throw new N5NoSuchKeyException("No such file", e);
154+
} catch (IOException | UncheckedIOException e ) {
155+
throw new N5IOException("Failed to truncate locked file channel", e);
156+
}
157+
}
158+
144159
@Override
145-
public Reader newReader() throws IOException {
160+
public Reader newReader() throws N5IOException {
146161

147162
return Channels.newReader(channel, StandardCharsets.UTF_8.name());
148163
}
149164

150165
@Override
151-
public Writer newWriter() throws IOException {
166+
public Writer newWriter() throws N5IOException {
152167

153-
channel.truncate(0);
168+
truncateChannel(0);
154169
return Channels.newWriter(channel, StandardCharsets.UTF_8.name());
155170
}
156171

157172
@Override
158-
public InputStream newInputStream() throws IOException {
173+
public InputStream newInputStream() throws N5IOException {
159174

160175
return Channels.newInputStream(channel);
161176
}
162177

163178
@Override
164-
public OutputStream newOutputStream() throws IOException {
179+
public OutputStream newOutputStream() throws N5IOException {
165180

166-
channel.truncate(0);
181+
truncateChannel(0);
167182
return Channels.newOutputStream(channel);
168183
}
169184

@@ -187,33 +202,49 @@ public FileSystemKeyValueAccess(final FileSystem fileSystem) {
187202
}
188203

189204
@Override
190-
public LockedFileChannel lockForReading(final String normalPath) throws IOException {
205+
public LockedChannel lockForReading(final String normalPath) throws N5IOException {
191206

192207
try {
193208
return new LockedFileChannel(normalPath, true);
194-
} catch (NoSuchFileException e) {
195-
throw new N5Exception.N5NoSuchKeyException("No such file", e);
209+
} catch (final NoSuchFileException e) {
210+
throw new N5NoSuchKeyException("No such file", e);
211+
} catch (IOException | UncheckedIOException e) {
212+
throw new N5IOException("Failed to lock file for reading: " + normalPath, e);
196213
}
197214
}
198215

199216
@Override
200-
public LockedFileChannel lockForWriting(final String normalPath) throws IOException {
217+
public LockedChannel lockForWriting(final String normalPath) throws N5IOException {
201218

202-
return new LockedFileChannel(normalPath, false);
219+
try {
220+
return new LockedFileChannel(normalPath, false);
221+
} catch (final NoSuchFileException e) {
222+
throw new N5NoSuchKeyException("No such file", e);
223+
} catch (IOException | UncheckedIOException e) {
224+
throw new N5IOException("Failed to lock file for writing: " + normalPath, e);
225+
}
203226
}
204227

205-
public LockedFileChannel lockForReading(final Path path) throws IOException {
228+
public LockedChannel lockForReading(final Path path) throws N5IOException {
206229

207230
try {
208231
return new LockedFileChannel(path, true);
209-
} catch (NoSuchFileException e) {
210-
throw new N5Exception.N5NoSuchKeyException("No such file", e);
232+
} catch (final NoSuchFileException e) {
233+
throw new N5NoSuchKeyException("No such file", e);
234+
} catch (IOException | UncheckedIOException e) {
235+
throw new N5IOException("Failed to lock file for reading: " + path, e);
211236
}
212237
}
213238

214-
public LockedFileChannel lockForWriting(final Path path) throws IOException {
239+
public LockedChannel lockForWriting(final Path path) throws N5IOException {
215240

216-
return new LockedFileChannel(path, false);
241+
try {
242+
return new LockedFileChannel(path, false);
243+
} catch (final NoSuchFileException e) {
244+
throw new N5NoSuchKeyException("No such file", e);
245+
} catch (IOException | UncheckedIOException e) {
246+
throw new N5IOException("Failed to lock file for writing: " + path, e);
247+
}
217248
}
218249

219250
@Override
@@ -238,25 +269,33 @@ public boolean exists(final String normalPath) {
238269
}
239270

240271
@Override
241-
public String[] listDirectories(final String normalPath) throws IOException {
272+
public String[] listDirectories(final String normalPath) throws N5IOException {
242273

243274
final Path path = fileSystem.getPath(normalPath);
244275
try (final Stream<Path> pathStream = Files.list(path)) {
245276
return pathStream
246277
.filter(a -> Files.isDirectory(a))
247278
.map(a -> path.relativize(a).toString())
248279
.toArray(n -> new String[n]);
280+
} catch (NoSuchFileException e) {
281+
throw new N5NoSuchKeyException("No such file", e);
282+
} catch (IOException | UncheckedIOException e) {
283+
throw new N5IOException("Failed to list directories", e);
249284
}
250285
}
251286

252287
@Override
253-
public String[] list(final String normalPath) throws IOException {
288+
public String[] list(final String normalPath) throws N5IOException {
254289

255290
final Path path = fileSystem.getPath(normalPath);
256291
try (final Stream<Path> pathStream = Files.list(path)) {
257292
return pathStream
258293
.map(a -> path.relativize(a).toString())
259294
.toArray(n -> new String[n]);
295+
} catch (NoSuchFileException e) {
296+
throw new N5NoSuchKeyException("No such file", e);
297+
} catch (IOException | UncheckedIOException e) {
298+
throw new N5IOException("Failed to list files", e);
260299
}
261300
}
262301

@@ -362,32 +401,42 @@ public String compose(final String... components) {
362401
}
363402

364403
@Override
365-
public void createDirectories(final String normalPath) throws IOException {
404+
public void createDirectories(final String normalPath) throws N5IOException {
366405

367-
createDirectories(fileSystem.getPath(normalPath));
406+
try {
407+
createDirectories(fileSystem.getPath(normalPath));
408+
} catch (NoSuchFileException e) {
409+
throw new N5NoSuchKeyException("No such file", e);
410+
} catch (IOException | UncheckedIOException e) {
411+
throw new N5IOException("Failed to create directories", e);
412+
}
368413
}
369414

370415
@Override
371-
public void delete(final String normalPath) throws IOException {
416+
public void delete(final String normalPath) throws N5IOException {
372417

373-
final Path path = fileSystem.getPath(normalPath);
418+
try {
419+
final Path path = fileSystem.getPath(normalPath);
374420

375-
if (Files.isRegularFile(path))
376-
try (final LockedChannel channel = lockForWriting(path)) {
377-
Files.delete(path);
378-
}
379-
else {
380-
try (final Stream<Path> pathStream = Files.walk(path)) {
381-
for (final Iterator<Path> i = pathStream.sorted(Comparator.reverseOrder()).iterator(); i.hasNext();) {
382-
final Path childPath = i.next();
383-
if (Files.isRegularFile(childPath))
384-
try (final LockedChannel channel = lockForWriting(childPath)) {
385-
Files.delete(childPath);
386-
}
387-
else
388-
tryDelete(childPath);
421+
if (Files.isRegularFile(path))
422+
try (final LockedChannel channel = lockForWriting(path)) {
423+
Files.delete(path);
424+
}
425+
else {
426+
try (final Stream<Path> pathStream = Files.walk(path)) {
427+
for (final Iterator<Path> i = pathStream.sorted(Comparator.reverseOrder()).iterator(); i.hasNext();) {
428+
final Path childPath = i.next();
429+
if (Files.isRegularFile(childPath))
430+
try (final LockedChannel channel = lockForWriting(childPath)) {
431+
Files.delete(childPath);
432+
}
433+
else
434+
tryDelete(childPath);
435+
}
389436
}
390437
}
438+
} catch (IOException | UncheckedIOException e) {
439+
throw new N5IOException("Failed to delete file at " + normalPath, e);
391440
}
392441
}
393442

0 commit comments

Comments
 (0)