C#文件读/写fileshare似乎不起作用

时间:2008-09-24 01:48:25

标签: c# binary fileshare

我的问题是基于继承了我不能做很多的遗留代码。基本上,我有一个会产生数据块的设备。一个将调用设备来创建该数据块的库,由于某种原因我不完全理解,即使我想要也不能改变,将该数据块写入磁盘。

此写入不是即时的,但最多可能需要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时断言,该事件表明另一个进程已打开该文件。

我正在设置MSDN上的FileStream文档中所述的FileAccess和FileShare枚举,但似乎我无法做我想做的事情(即,在一个线程中写入,在另一个线程中读取)。我意识到这个应用程序有点不正统,但是当我得到实际的设备时,我将不得不做同样的事情,但是使用MFC。

无论如何,我忘记了什么?我想要做什么,因为它在文档中被指定为可能?

谢谢! MMR

3 个答案:

答案 0 :(得分:37)

您的消费者必须指定FileShare.ReadWrite。

尝试在消费者中将文件作为FileShare.Read打开时,您说“我想打开文件并让其他人同时阅读”......因为已经如果调用失败,则必须允许与读者进行并发写入。

答案 1 :(得分:3)

我没有时间测试这个,但我认为你可能需要调用BinaryWriter的Flush方法

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;
    theBinaryWriter.Flush();
}
theFS.Close();

抱歉,我没有时间对此进行测试。我遇到了一个问题,我正在创建一个与此类似的文件(尽管不完全正确),并且缺少“Flush”是罪魁祸首。

答案 2 :(得分:3)

我相信Chuck是对的,但请记住,这完全可行的唯一原因是因为文件系统足够聪明,可以序列化您的读/写;你没有锁定文件资源 - 这不是一件好事:)