diff --git a/lib/base.php b/lib/base.php
index 336ff9fa231fbec4a53c49eeef4b7bc30636270c..4e24f9f44ac96c5ee44ece8b0436a7cef3e82d1c 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -148,6 +148,7 @@ class OC{
 		require_once('streamwrappers.php');
 		stream_wrapper_register("fakedir", "OC_FakeDirStream");
 		stream_wrapper_register('static', 'OC_StaticStreamWrapper');
+		stream_wrapper_register('close', 'OC_CloseStreamWrapper');
 		
 		// calculate the documentroot
 		OC::$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']);
diff --git a/lib/streamwrappers.php b/lib/streamwrappers.php
index 05d5598819a1488306b47f9935bef64edf473fa9..f1e0fa0e1d9cadffdca404212b1630ae87a80905 100644
--- a/lib/streamwrappers.php
+++ b/lib/streamwrappers.php
@@ -218,3 +218,89 @@ class OC_StaticStreamWrapper {
 		return false;
 	}
 }
+
+/**
+ * stream wrapper that provides a callback on stream close
+ */
+class OC_CloseStreamWrapper{
+	public static $callBacks=array();
+	private $path='';
+	private $source;
+	private static $open=array();
+	public function stream_open($path, $mode, $options, &$opened_path){
+		$path=substr($path,strlen('close://'));
+		$this->path=$path;
+		$this->source=fopen($path,$mode);
+		if(is_resource($this->source)){
+			$this->meta=stream_get_meta_data($this->source);
+		}
+		self::$open[]=$path;
+		return is_resource($this->source);
+	}
+
+	public function stream_seek($offset, $whence=SEEK_SET){
+		fseek($this->source,$offset,$whence);
+	}
+
+	public function stream_tell(){
+		return ftell($this->source);
+	}
+
+	public function stream_read($count){
+		return fread($this->source,$count);
+	}
+
+	public function stream_write($data){
+		return fwrite($this->source,$data);
+	}
+
+	public function stream_set_option($option,$arg1,$arg2){
+		switch($option){
+			case STREAM_OPTION_BLOCKING:
+				stream_set_blocking($this->source,$arg1);
+				break;
+			case STREAM_OPTION_READ_TIMEOUT:
+				stream_set_timeout($this->source,$arg1,$arg2);
+				break;
+			case STREAM_OPTION_WRITE_BUFFER:
+				stream_set_write_buffer($this->source,$arg1,$arg2);
+		}
+	}
+
+	public function stream_stat(){
+		return fstat($this->source);
+	}
+
+	public function stream_lock($mode){
+		flock($this->source,$mode);
+	}
+
+	public function stream_flush(){
+		return fflush($this->source);
+	}
+
+	public function stream_eof(){
+		return feof($this->source);
+	}
+
+	public function url_stat($path) {
+		$path=substr($path,strlen('close://'));
+		if(file_exists($path)){
+			return stat($path);
+		}else{
+			return false;
+		}
+	}
+
+	public function stream_close(){
+		fclose($this->source);
+		if(isset(self::$callBacks[$this->path])){
+			call_user_func(self::$callBacks[$this->path],$this->path);
+		}
+	}
+
+	public function unlink($path){
+		$path=substr($path,strlen('close://'));
+		return unlink($path);
+	}
+}
diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php
index c4784a62976a1c924839ad73fc7b6e9537d7bd96..17a92c6658c1f12e6a4d490821af44dc605112ae 100644
--- a/tests/lib/streamwrappers.php
+++ b/tests/lib/streamwrappers.php
@@ -44,4 +44,35 @@ class Test_StreamWrappers extends UnitTestCase {
 		clearstatcache();
 		$this->assertFalse(file_exists($staticFile));
 	}
+
+	public function testCloseStream(){
+		//ensure all basic stream stuff works
+		$sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt';
+		$tmpFile=OC_Helper::TmpFile('.txt');
+		$file='close://'.$tmpFile;
+		$this->assertTrue(file_exists($file));
+		file_put_contents($file,file_get_contents($sourceFile));
+		$this->assertEqual(file_get_contents($sourceFile),file_get_contents($file));
+		unlink($file);
+		clearstatcache();
+		$this->assertFalse(file_exists($file));
+		
+		//test callback
+		$tmpFile=OC_Helper::TmpFile('.txt');
+		$file='close://'.$tmpFile;
+		OC_CloseStreamWrapper::$callBacks[$tmpFile]=array('Test_StreamWrappers','closeCallBack');
+		$fh=fopen($file,'w');
+		fwrite($fh,'asd');
+		try{
+			fclose($fh);
+			$this->fail('Expected exception');
+		}catch(Exception $e){
+			$path=$e->getMessage();
+			$this->assertEqual($path,$tmpFile);
+		}
+	}
+
+	public static function closeCallBack($path){
+		throw new Exception($path);
+	}
 }
\ No newline at end of file