我的问题是基于继承了我不能做很多的遗留代码.基本上,我有一个会产生数据块的设备.一个将调用设备来创建该数据块的库,由于某种原因我不完全理解并且即使我想要也不能改变,将该数据块写入磁盘.
此写入不是即时的,但最多可能需要90秒.在那个时候,用户想要获得正在生成的数据的部分视图,所以我想要一个消费者线程来读取另一个库写入磁盘的数据.
在我触摸这个遗留代码之前,我想使用完全控制的代码模仿问题.我正在使用C#,表面上是因为它提供了我想要的许多功能.
在生成器类中,我有这个代码创建一个随机数据块:
FileStream theFS = new FileStream(this.ScannerRawFileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); //note that I need to be able to read this elsewhere... BinaryWriter theBinaryWriter = new BinaryWriter(theFS); int y, x; for (y = 0; y < imheight; y++){ ushort[] theData= new ushort[imwidth]; for(x = 0; x < imwidth;x++){ theData[x] = (ushort)(2*y+4*x); } byte[] theNewArray = new byte[imwidth * 2]; Buffer.BlockCopy(theImage, 0, theNewArray, 0, imwidth * 2); theBinaryWriter.Write(theNewArray); Thread.Sleep(mScanThreadWait); //sleep for 50 milliseconds Progress = (float)(y-1 >= 0 ? y-1 : 0) / (float)imheight; } theFS.Close();
到现在为止还挺好.这段代码有效.当前版本(使用FileStream和BinaryWriter)看起来与使用相同选项的File.Open和写入磁盘的ushort []上的BinaryFormatter相同(虽然速度较慢,因为复制).
但后来我添加了一个消费者线程:
FileStream theFS; if (!File.Exists(theFileName)) { //do error handling return; } else { theFS = new FileStream(theFileName, FileMode.Open, FileAccess.Read, FileShare.Read); //very relaxed file opening } BinaryReader theReader = new BinaryReader(theFS); //gotta do this copying in order to handle byte array swaps //frustrating, but true. byte[] theNewArray = theReader.ReadBytes( (int)(imheight * imwidth * inBase.Progress) * 2); ushort[] theData = new ushort[((int)(theNewArray.Length/2))]; Buffer.BlockCopy(theNewArray, 0, theData, 0, theNewArray.Length);
现在,NewArray的声明可能会被破坏,并会导致某种读取溢出.但是,这段代码永远不会那么远,因为它始终总是在尝试使用System.IO.IOException打开新的FileStream时断言,该System.IO.IOException指出另一个进程已打开该文件.
我正在设置MSDN上的FileStream文档中所述的FileAccess和FileShare枚举,但看起来我无法做我想做的事情(即,在一个线程中写入,在另一个线程中读取).我意识到这个应用程序有点不正统,但是当我得到实际的设备时,我将不得不做同样的事情,但使用MFC.
无论如何,我忘记了什么?我想要做什么,因为它在文档中被指定为可能?
谢谢!MMR
您的使用者必须指定FileShare.ReadWrite.
通过尝试在消费者中将文件作为FileShare.Read打开,您说"我想打开文件并让其他人同时阅读"...因为已经有一个调用失败的编写者,您必须允许与读者并发写入.