diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php
index 4c0ffa978ed8e8d5ce1be8fc68c85692d61e10ff..1c90954cec8840215d93bd605bd20c6a478f0f01 100644
--- a/apps/files_encryption/lib/crypt.php
+++ b/apps/files_encryption/lib/crypt.php
@@ -206,12 +206,16 @@ class OC_Crypt {
 	/**
 	 * decrypt data in 8192b sized blocks
 	 */
-	public static function blockDecrypt($data, $key=''){
+	public static function blockDecrypt($data, $key='',$maxLength=0){
 		$result='';
 		while(strlen($data)){
 			$result.=self::decrypt(substr($data,0,8192),$key);
 			$data=substr($data,8192);
 		}
-		return rtrim($result, "\0");
+		if($maxLength>0){
+			return substr($result,0,$maxLength);
+		}else{
+			return rtrim($result, "\0");
+		}
 	}
 }
diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php
index 64fec381dedbc4a12e12ba7bc1912fa1cbbd5e84..4ef7d1e08bb9c06f0fbd1c01bc9482040d2ab51b 100644
--- a/apps/files_encryption/lib/cryptstream.php
+++ b/apps/files_encryption/lib/cryptstream.php
@@ -35,6 +35,7 @@ class OC_CryptStream{
 	private $meta=array();//header/meta for source stream
 	private $count;
 	private $writeCache;
+	private $size;
 	private static $rootView;
 
 	public function stream_open($path, $mode, $options, &$opened_path){
@@ -45,8 +46,14 @@ class OC_CryptStream{
 		if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])){
 			$this->source=self::$sourceStreams[basename($path)]['stream'];
 			$this->path=self::$sourceStreams[basename($path)]['path'];
+			$this->size=self::$sourceStreams[basename($path)]['size'];
 		}else{
 			$this->path=$path;
+			if($mode=='w' or $mode=='w+' or $mode=='wb' or $mode=='wb+'){
+				$this->size=0;
+			}else{
+				$this->size=self::$rootView->filesize($path,$mode);
+			}
 			OC_FileProxy::$enabled=false;//disable fileproxies so we can open the source file
 			$this->source=self::$rootView->fopen($path,$mode);
 			OC_FileProxy::$enabled=true;
@@ -77,14 +84,16 @@ class OC_CryptStream{
 			OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL);
 			die();
 		}
+		$pos=ftell($this->source);
 		$data=fread($this->source,8192);
 		if(strlen($data)){
 			$result=OC_Crypt::decrypt($data);
 		}else{
 			$result='';
 		}
-		if($this->stream_eof()){
-			$result=rtrim($result, "\0");
+		$length=$this->size-$pos;
+		if($length<8192){
+			$result=substr($result,0,$length);
 		}
 		return $result;
 	}
@@ -116,6 +125,8 @@ class OC_CryptStream{
 				$data=substr($data,8192);
 			}
 		}
+		$currentPos=ftell($this->source);
+		$this->size=max($this->size,$currentPos);
 		return $length;
 	}
 
@@ -159,7 +170,7 @@ class OC_CryptStream{
 	public function stream_close(){
 		$this->flush();
 		if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
-			OC_FileCache::put($this->path,array('encrypted'=>true),'');
+			OC_FileCache::put($this->path,array('encrypted'=>true,'size'=>$this->size),'');
 		}
 		return fclose($this->source);
 	}
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index b9e719448a3b5087195f8f3ed0a97510586a5b2f..f25e4a662f6ea568bcc6dc245dcef240780041f1 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -66,15 +66,17 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
 	public function preFile_put_contents($path,&$data){
 		if(self::shouldEncrypt($path)){
 			if (!is_resource($data)) {//stream put contents should have been converter to fopen
+				$size=strlen($data);
 				$data=OC_Crypt::blockEncrypt($data);
-				OC_FileCache::put($path,array('encrypted'=>true),'');
+				OC_FileCache::put($path,array('encrypted'=>true,'size'=>$size),'');
 			}
 		}
 	}
 	
 	public function postFile_get_contents($path,$data){
 		if(self::isEncrypted($path)){
-			$data=OC_Crypt::blockDecrypt($data);
+			$cached=OC_FileCache_Cached::get($path,'');
+			$data=OC_Crypt::blockDecrypt($data,'',$cached['size']);
 		}
 		return $data;
 	}
@@ -108,4 +110,21 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
 		}
 		return $mime;
 	}
+
+	public function postStat($path,$data){
+		if(self::isEncrypted($path)){
+			$cached=OC_FileCache_Cached::get($path,'');
+			$data['size']=$cached['size'];
+		}
+		return $data;
+	}
+
+	public function postFileSize($path,$size){
+		if(self::isEncrypted($path)){
+			$cached=OC_FileCache_Cached::get($path,'');
+			return  $cached['size'];
+		}else{
+			return $size;
+		}
+	}
 }
diff --git a/apps/files_encryption/tests/encryption.php b/apps/files_encryption/tests/encryption.php
index 70aa1daf4c3f4f83933fcf763eed5a76504777ed..286770a69f51b5abcb882ac1e7cf6b4d5e94edae 100644
--- a/apps/files_encryption/tests/encryption.php
+++ b/apps/files_encryption/tests/encryption.php
@@ -66,7 +66,7 @@ class Test_Encryption extends UnitTestCase {
 		$this->assertEqual($decrypted,$source);
 
 		$encrypted=OC_Crypt::blockEncrypt($source,$key);
-		$decrypted=OC_Crypt::blockDecrypt($encrypted,$key);
+		$decrypted=OC_Crypt::blockDecrypt($encrypted,$key,strlen($source));
 		$this->assertEqual($decrypted,$source);
 	}
 }
diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php
index 5616e2091a9e85e245e9409853dac552b0eae24b..4533289265a316abc47e96299da1125990288048 100644
--- a/apps/files_encryption/tests/proxy.php
+++ b/apps/files_encryption/tests/proxy.php
@@ -50,6 +50,7 @@ class Test_CryptProxy extends UnitTestCase {
 		
 		$fromFile=OC_Filesystem::file_get_contents('/file');
 		$this->assertNotEqual($original,$stored);
+		$this->assertEqual(strlen($original),strlen($fromFile));
 		$this->assertEqual($original,$fromFile);
 
 	}
@@ -88,6 +89,20 @@ class Test_CryptProxy extends UnitTestCase {
 
 		$fromFile=OC_Filesystem::file_get_contents('/file');
 		$this->assertNotEqual($original,$stored);
+		$this->assertEqual(strlen($original),strlen($fromFile));
 		$this->assertEqual($original,$fromFile);
+
+		$file=__DIR__.'/zeros';
+		$original=file_get_contents($file);
+
+		OC_Filesystem::file_put_contents('/file',$original);
+
+		OC_FileProxy::$enabled=false;
+		$stored=OC_Filesystem::file_get_contents('/file');
+		OC_FileProxy::$enabled=true;
+
+		$fromFile=OC_Filesystem::file_get_contents('/file');
+		$this->assertNotEqual($original,$stored);
+		$this->assertEqual(strlen($original),strlen($fromFile));
 	}
 }
diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php
index 4ffeb6210a9d18f871b828c6396cda93cca75fbd..d95ea792f729ba24b1c98e588bab8d291e011cb2 100644
--- a/apps/files_encryption/tests/stream.php
+++ b/apps/files_encryption/tests/stream.php
@@ -10,23 +10,23 @@ class Test_CryptStream extends UnitTestCase {
 	private $tmpFiles=array();
 	
 	function testStream(){
-		$stream=$this->getStream('test1','w');
+		$stream=$this->getStream('test1','w',strlen('foobar'));
 		fwrite($stream,'foobar');
 		fclose($stream);
 
-		$stream=$this->getStream('test1','r');
+		$stream=$this->getStream('test1','r',strlen('foobar'));
 		$data=fread($stream,6);
 		fclose($stream);
 		$this->assertEqual('foobar',$data);
 
 		$file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
 		$source=fopen($file,'r');
-		$target=$this->getStream('test2','w');
+		$target=$this->getStream('test2','w',0);
 		OCP\Files::streamCopy($source,$target);
 		fclose($target);
 		fclose($source);
 
-		$stream=$this->getStream('test2','r');
+		$stream=$this->getStream('test2','r',filesize($file));
 		$data=stream_get_contents($stream);
 		$original=file_get_contents($file);
 		$this->assertEqual(strlen($original),strlen($data));
@@ -37,9 +37,10 @@ class Test_CryptStream extends UnitTestCase {
 	 * get a cryptstream to a temporary file
 	 * @param string $id
 	 * @param string $mode
+	 * @param int size
 	 * @return resource
 	 */
-	function getStream($id,$mode){
+	function getStream($id,$mode,$size){
 		if($id===''){
 			$id=uniqid();
 		}
@@ -50,7 +51,7 @@ class Test_CryptStream extends UnitTestCase {
 			$file=$this->tmpFiles[$id];
 		}
 		$stream=fopen($file,$mode);
-		OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream);
+		OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream,'size'=>$size);
 		return fopen('crypt://streams/'.$id,$mode);
 	}
 
@@ -58,11 +59,24 @@ class Test_CryptStream extends UnitTestCase {
 		$file=__DIR__.'/binary';
 		$source=file_get_contents($file);
 
-		$stream=$this->getStream('test','w');
+		$stream=$this->getStream('test','w',strlen($source));
 		fwrite($stream,$source);
 		fclose($stream);
 
-		$stream=$this->getStream('test','r');
+		$stream=$this->getStream('test','r',strlen($source));
+		$data=stream_get_contents($stream);
+		fclose($stream);
+		$this->assertEqual(strlen($data),strlen($source));
+		$this->assertEqual($source,$data);
+
+		$file=__DIR__.'/zeros';
+		$source=file_get_contents($file);
+
+		$stream=$this->getStream('test2','w',strlen($source));
+		fwrite($stream,$source);
+		fclose($stream);
+
+		$stream=$this->getStream('test2','r',strlen($source));
 		$data=stream_get_contents($stream);
 		fclose($stream);
 		$this->assertEqual(strlen($data),strlen($source));
diff --git a/apps/files_encryption/tests/zeros b/apps/files_encryption/tests/zeros
new file mode 100644
index 0000000000000000000000000000000000000000..ff982acf423cad62041f225497e099ba5520961c
Binary files /dev/null and b/apps/files_encryption/tests/zeros differ
diff --git a/lib/filecache.php b/lib/filecache.php
index 9963a5a3baf66be27ab4f5b4917b0995be8356eb..d5458834e08277d1e3d3107cfea475c8323c8e93 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -68,18 +68,18 @@ class OC_FileCache{
 		$path=$root.$path;
 		$parent=self::getParentId($path);
 		$id=self::getId($path,'');
-		if($id!=-1){
-			self::update($id,$data);
-			return;
-		}
 		if(isset(OC_FileCache_Cached::$savedData[$path])){
-			$data=array_merge($data,OC_FileCache_Cached::$savedData[$path]);
+			$data=array_merge(OC_FileCache_Cached::$savedData[$path],$data);
 			unset(OC_FileCache_Cached::$savedData[$path]);
 		}
 		if(!isset($data['size']) or !isset($data['mtime'])){//save incomplete data for the next time we write it
 			OC_FileCache_Cached::$savedData[$path]=$data;
 			return;
 		}
+		if($id!=-1){
+			self::update($id,$data);
+			return;
+		}
 		if(!isset($data['encrypted'])){
 			$data['encrypted']=false;
 		}