2013-02-09 30 views
1

我正在實現一些文件支持的數據結構,並使用隨機讀取和寫入訪問來更新結構。flash.filesystem.FileStream或Developer Error中的數據損壞問題?

並偶然發現一個錯誤的bug或我的代碼是不正確的。

經過幾個小時的檢查和調試,它歸結爲下面的代碼片段,它隔離了錯誤的?行爲。

在循環內部,我認爲是寫入,讀取和覆蓋位置0處的字節。 在代碼運行後,您會期望得到包含1個字節0x39的文件。 而是文件增長,書寫不發生在位置0,但在EOF。多次運行代碼將導致文件越來越大。

如果您對線條fs.readByte();發表評論,則代碼的行爲與預期相同。

import flash.filesystem.File; 
import flash.filesystem.FileStream; 
import flash.filesystem.FileMode; 

var tf:File=File.userDirectory.resolvePath("test.txt"); 
var fs:FileStream=new FileStream(); 

fs.open(tf,FileMode.UPDATE); 

for (var i=0;i<10;i++){ 
    fs.position=0; 
    fs.writeByte(0x30+i); 
    fs.position=0; 
    fs.readByte(); //if you comment this line out, results are as expected 
} 

fs.close(); 
trace(tf.size); 

請,如果有人正在測試這一點,並得出相同的結論作爲我來說,這是 一個bug,請投在Adobe的bugbase這個bug,所以他們希望考慮將其固定。

VOTE BUG at ADOBE's bugbase

否則,如果有人能告訴我我做錯了什麼,我將不勝感激。

TX利奧

編輯:澄清

//Alright, since the loop example caused some confusion about whether or not 
//there would be use for such code I'll try with another snippet, that is hopefully 
//closer to some real application. 
// 
//The code updates some bytes in the file 
//and afterwards reads some bytes somewhere else in the file, eg. a header field. 
//This time not in a loop but triggered by a timer, which could of course also 
//be some event handler. 
// 
//I hope this makes the problem more apparent 

import flash.utils.ByteArray; 
import flash.filesystem.File; 
import flash.filesystem.FileStream; 
import flash.filesystem.FileMode; 


var tf=File.userDirectory.resolvePath("test.txt"); 
var fs:FileStream=new FileStream(); 
var timerID:int; 
var count:int=0; 

var fileAction:Function=function(){ 
    var dataToWrite:ByteArray=new ByteArray(); 
    var dataToRead:ByteArray=new ByteArray(); 

    dataToWrite[0]=0x31; 
    dataToWrite[1]=0x32; 

    fs.position=2; 
    fs.writeBytes(dataToWrite); 
    fs.position=0; 
    fs.readBytes(dataToRead,0,2); //this read will corrupt the previous write!!! 
            //instead updating two bytes at 0x02 
            //it will write to the end of file, 
            //appending two bytes 
    count++; 
    if (count>10) { 
     clearInterval(timerID); 
     fs.close(); 
     trace("Excpected file size: 4") 
     trace("Actual size: "+tf.size); 

    } 

} 

fs.open(tf,FileMode.UPDATE); 
fs.position=0; 
fs.writeByte(0x30); 
fs.writeByte(0x30); 

timerID=setInterval(fileAction,100); 

回答

0

雖然我同意你的預期是基於對文檔的創建,我不知道有什麼用是讀剛纔所寫的數據,特別是在對象的一個​​循環中,因爲這是一次不必要的性能下降。你能提供一個用例嗎?

也許在FileStream API中存在無法限制的限制,可以避免過度緩慢或阻礙同步或異步處理。

如果這是一個循環內寫完後,你必須讀一個字節,你可以用ByteArray對象,然後將一次寫入FileStream

package 
{ 
    //Imports 
    import flash.display.Sprite; 
    import flash.filesystem.File; 
    import flash.filesystem.FileStream; 
    import flash.filesystem.FileMode; 
    import flash.utils.ByteArray; 

    //Class 
    public class Main extends Sprite 
    { 
     //Constructor 
     public function Main():void 
     { 
      var ba:ByteArray = new ByteArray(); 

      for (var i:uint = 0; i < 10; i++) 
      { 
       ba.position = 0; 
       ba.writeByte(0x30 + i); 
       ba.position = 0; 
       ba.readByte(); 
      } 

      var fs:FileStream = new FileStream(); 
      var tf:File = File.desktopDirectory.resolvePath("test.txt"); 

      fs.open(tf, FileMode.UPDATE); 
      fs.writeBytes(ba); 
      fs.close(); 

      trace(tf.size); 
     } 
    } 
} 
+0

的代碼片段沒有做任何事情,除了這樣做暴露這個錯誤,沒有真正的用處。問題在於** READ打破了先前的WRITE **,這是一個嚴重的錯誤,並導致數據損壞。另外,如果您讀取已寫入的數據或任何其他數據,我認爲這不重要。 – leostone 2013-02-10 09:44:44

+0

請參閱原始問題中的編輯以獲得更好的代碼示例 – leostone 2013-02-10 12:39:54