In the second part of this series, I’ve
covered caveats when using the Source
and Sink
interfaces.
This time, I’ll look into another useful abstraction, the Store
interface.
Now, what is this interface? Here it comes:
public interface Store extends Source, Sink {
void delete() throws IOException;
boolean exists();
int BUFSIZE = 8 * 1024;
}
Simply put, a Store
is a combination of a Source
and a Sink
which allows you to delete
its data from the
underlying entity, e.g. a file, and test if it exists
.
BUFSIZE
is a useful constant for allocating buffers.
Now what makes this interface so powerful is that its simple and storage-media-neutral:
Implementations could store the data in a file, a preferences node, an array on the heap, a database record or whatever
you can imagine.
Here’s a straightforward implementation which uses a File
:
public final class FileStore implements Store {
private final File file;
public FileStore(final File file) { this.file = Objects.requireNonNull(file); }
@Override public InputStream input() throws IOException {
return new FileInputStream(file);
}
@Override public OutputStream output() throws IOException {
return new FileOutputStream(file);
}
@Override public void delete() throws IOException {
if (!file.delete())
throw new FileNotFoundException(file + (cannot delete));
}
@Override public boolean exists() { return file.exists(); }
}
I’ve declared this class final
because there is nothing reasonable to customize in a subclass and I like to follow the
“design for inheritance or inhibit it” strategy.
An alternative implementation, let’s call it MemoryStore
, could store the data in an array on the heap.
This is particularly useful for unit testing where you would inject a MemoryStore
into the class under test.
I’ll leave the implementation to you as an exercise.
Here’s how to use a Store
with the general-purpose copy-algorithm introduced in part one:
Store source = ... // some store
Store sink = ... // some store
Copy.copy(source, sink);
Note that the copy
-method is just relying on the Source
and Sink
super-interfaces of the Store
interface.
Enjoy!