我正在实现一些由文件支持的数据结构,并使用随机读写访问来更新结构。
发现了一个坏错误或我的代码不正确。
经过几个小时的检查和调试,它归结为以下代码片段,将错误隔离开来?行为。
在循环内部我应该写入,读取并覆盖位置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,所以他们希望考虑修复它。
否则,如果有人能告诉我我做错了什么,我将不胜感激。
tx leo
编辑:一些澄清
//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 :(得分:0)
虽然我同意您的期望是基于文档建立的,但我不确定它是什么用于阅读刚刚编写的内容,尤其是在FileStream
对象的循环中,因为它是不必要的性能打击。你能提供一个用例吗?
在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);
}
}
}