diff --git a/api/net/sf/briar/api/transport/batch/BatchTransportReader.java b/api/net/sf/briar/api/transport/batch/BatchTransportReader.java
index 486f441d49b2c5233926fb1fc63264523b4b0576..031fb754186c54dd989bb04a7d43b0bcc6d2aabb 100644
--- a/api/net/sf/briar/api/transport/batch/BatchTransportReader.java
+++ b/api/net/sf/briar/api/transport/batch/BatchTransportReader.java
@@ -13,9 +13,14 @@ public interface BatchTransportReader {
 	InputStream getInputStream();
 
 	/**
-	 * Closes the reader and disposes of any associated state. This method must
-	 * be called even if the reader is not used, or if an exception is thrown
-	 * while using the reader.
+	 * Finishes reading from the transport. This method should be called after
+	 * closing the input stream.
+	 */
+	void finish() throws IOException;
+
+	/**
+	 * Disposes of any associated state. This method must be called even if the
+	 * reader is not used, or if an exception is thrown while using the reader.
 	 */
 	void dispose() throws IOException;
 }
diff --git a/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java b/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java
index d90a4501879288e7330cf153272f5aab1359cc1a..c66edb69f656eedd7a4d05b68647e8a02ac286a9 100644
--- a/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java
+++ b/api/net/sf/briar/api/transport/stream/StreamTransportConnection.java
@@ -18,9 +18,15 @@ public interface StreamTransportConnection {
 	OutputStream getOutputStream() throws IOException;
 
 	/**
-	 * Closes the connection and disposes of any associated state. This method
-	 * must be called even if the connection is not used, or if an exception
-	 * is thrown while using the connection.
+	 * Finishes using the transport. This method should be called after closing
+	 * the input and output streams.
+	 */
+	void finish() throws IOException;
+
+	/**
+	 * Disposes of any associated state. This method must be called even if the
+	 * connection is not used, or if an exception is thrown while using the
+	 * connection.
 	 */
 	void close() throws IOException;
 }
diff --git a/components/net/sf/briar/plugins/file/FilePlugin.java b/components/net/sf/briar/plugins/file/FilePlugin.java
index 20191a930d1c84effe724eea0c88c93959ea8649..1ca4e7fd87cf9765f1d35520f16ccfc354bf3056 100644
--- a/components/net/sf/briar/plugins/file/FilePlugin.java
+++ b/components/net/sf/briar/plugins/file/FilePlugin.java
@@ -32,6 +32,7 @@ abstract class FilePlugin implements BatchTransportPlugin {
 
 	protected abstract File chooseOutputDirectory();
 	protected abstract void writerFinished(File f);
+	protected abstract void readerFinished(File f);
 
 	FilePlugin(Executor executor) {
 		this.executor = executor;
@@ -138,7 +139,8 @@ abstract class FilePlugin implements BatchTransportPlugin {
 			if(f.length() < TransportConstants.MIN_CONNECTION_LENGTH) return;
 			try {
 				FileInputStream in = new FileInputStream(f);
-				callback.readerCreated(new FileTransportReader(f, in));
+				callback.readerCreated(new FileTransportReader(f, in,
+						FilePlugin.this));
 			} catch(IOException e) {
 				return;
 			}
diff --git a/components/net/sf/briar/plugins/file/FileTransportReader.java b/components/net/sf/briar/plugins/file/FileTransportReader.java
index 50f6b55574aacbeb5c370d629cf6187ad1326611..c44976ca5ac5a6dc0c5fee6404ad69e6b21ba781 100644
--- a/components/net/sf/briar/plugins/file/FileTransportReader.java
+++ b/components/net/sf/briar/plugins/file/FileTransportReader.java
@@ -10,12 +10,14 @@ class FileTransportReader implements BatchTransportReader {
 
 	private final File file;
 	private final InputStream in;
+	private final FilePlugin plugin;
 
 	private boolean streamInUse = false;
 
-	FileTransportReader(File file, InputStream in) {
+	FileTransportReader(File file, InputStream in, FilePlugin plugin) {
 		this.file = file;
 		this.in = in;
+		this.plugin = plugin;
 	}
 
 	public InputStream getInputStream() {
@@ -23,6 +25,11 @@ class FileTransportReader implements BatchTransportReader {
 		return in;
 	}
 
+	public void finish() throws IOException {
+		streamInUse = false;
+		plugin.readerFinished(file);
+	}
+
 	public void dispose() throws IOException {
 		if(streamInUse) in.close();
 		file.delete();
diff --git a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java
index e0f3523ae6e6c75daae6a05f908bebba18092d4f..e3df83ed704921908396aac37cd925918e561200 100644
--- a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java
+++ b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java
@@ -65,6 +65,11 @@ implements RemovableDriveMonitor.Callback {
 		}
 	}
 
+	@Override
+	protected void readerFinished(File f) {
+		callback.showMessage("REMOVABLE_DRIVE_READ_FINISHED");
+	}
+
 	@Override
 	protected void writerFinished(File f) {
 		callback.showMessage("REMOVABLE_DRIVE_WRITE_FINISHED");