C# 在ASP.NET MVC中将FileShare.ReadWrite与HttpPostedFile一起使用

C# 在ASP.NET MVC中将FileShare.ReadWrite与HttpPostedFile一起使用,c#,.net,asp.net-mvc,stream,file-permissions,C#,.net,Asp.net Mvc,Stream,File Permissions,我正在使用下面的代码将已发布的文件保存到服务器,但该文件正在不断读取,需要使用FileShare.ReadWrite,以便不会出现锁定错误 httpRequest.Files[0].SaveAs(filePath); 下面是我的阅读方法,如何使用HttpPosted文件实现这一点是具有最佳性能的正确方法 using (var fileStream = new FileStream( fileLocation, Fil

我正在使用下面的代码将已发布的文件保存到服务器,但该文件正在不断读取,需要使用FileShare.ReadWrite,以便不会出现锁定错误

 httpRequest.Files[0].SaveAs(filePath);
下面是我的阅读方法,如何使用HttpPosted文件实现这一点是具有最佳性能的正确方法

using (var fileStream = new FileStream(
                   fileLocation,
                   FileMode.Open,
                   FileAccess.Read,
                   FileShare.ReadWrite))
                {
                    using (var streamReader = new StreamReader(fileStream))
                    {
                        xDocument = XDocument.Parse(streamReader.ReadToEnd());
                    }
                }
这是我最好的选择吗

 using (var memoryStream = new MemoryStream())
                {
                    httpRequest.Files[0].InputStream.CopyTo(memoryStream);
                    var bytes = memoryStream.ToArray();

                    using (var fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
                    {
                        fs.Write(bytes, 0, bytes.Length);
                    }
                }
问题:
  • 您需要一个“写:一次,读:多”锁
假设:
  • 文件小(平均写入操作为5000毫秒)
  • 没有其他写入或读取操作(只有一个程序具有2个函数)
  • 你读文件比写文件多得多
解决方案

使用制度;
使用System.IO;
使用系统线程;
使用System.Web.Mvc;
命名空间stackoverflow_56307594.0
{
公共类HomeController:控制器
{
公众行动结果A()
{
readFile();
返回视图();
}
公共行动结果B()
{
writeFile();
返回视图();
}
私有静态对象writeLock=新对象();
私有void readFile()
{
while(!Monitor.TryEnter(writeLock,5000));//等待5000毫秒,等待writeLock(序列化访问)
使用(var stream=newfilestream(“filePath”,FileMode.Open,FileAccess.Read,FileShare.Read))
使用(变量读取器=新的流读取器(流))
{
//主动读取
//xDocument=xDocument.Parse(streamReader.ReadToEnd());
}
}
私有void writeFile()
{
锁(写锁)
{
FileStream=null;
while(stream==null)//等待活动读取
{
尝试
{
stream=newfilestream(“filePath”,FileMode.Open,FileAccess.ReadWrite,FileShare.None);
}
捕获(IOException)
{
//如果活动读取becase FileShare,则将失败。而(流==null)将等待无
}
}
Request.Files[0].InputStream.CopyTo(流);
}//解锁
}
}
}
注:
  • 我没有测试负载,也没有在Web服务器上测试解决方案

  • 我只在纸上测试过,我知道@efaruk现在删除了答案不是问题,但它是答案吗?这里有一个更好的方法来检查文件是否真的被锁定了:-我得到了与您大致相同的代码,并对其进行了测试。如果您阅读了许多评论,那么即使在最轻微的竞争条件下,也可能存在文件锁定问题和性能问题。我会选择具有内置错误处理和容错功能的Polly.Net框架……我的问题不是关于这一点,而是从HTTPPosted文件中执行它。这是怎么回事?从根本上说,您正在向磁盘写入数据,并且在同一个文件中从磁盘读取数据。您得到一个文件锁定错误。您提到了
    FileAccess
    FileShare
    标志来解决这个问题,然后是性能问题,正如我提到的,我得到了与您相同的代码。它表现得很好。那么问题是什么?在ASP.NET MVC中将FileShare.ReadWrite与HttpPostedFile一起使用-您必须使用内存、提到的@efaruk的MQ或dB。让我仔细检查一下doco
    HttpPostedFile
    没有给你那种控制权。我知道它没有,这就是为什么我要求从httpposted文件中选择一种替代方法,甚至给出了一个例子。不,它不支持:-当上传文件时,不从文件中读取信号。或者将文件上载为两步流程,将其上载到DataGrid,然后单击按钮处理将合并/向上插入新值/更改值的数据。
    Request.Files[0]。InputStream.CopyTo(stream)似乎不正确place@MikeFlynn变量
    超出范围,请查看code@MikeFlynn谢谢