在 ASP.NET MVC 中使用 FileShare.ReadWrite 和 HttpPostedFile
Posted
技术标签:
【中文标题】在 ASP.NET MVC 中使用 FileShare.ReadWrite 和 HttpPostedFile【英文标题】:Use FileShare.ReadWrite with HttpPostedFile in ASP.NET MVC 【发布时间】:2019-10-11 22:32:17 【问题描述】:我正在使用下面的代码将发布的文件保存到服务器,但该文件正在被持续读取,需要使用 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);
【问题讨论】:
我知道@efaruk 现在删除的答案不是问题,但它是答案吗?这是检查文件是否实际锁定的更好方法:***.com/a/11060322/495455 - 我的代码与您大致相同,并且我对其进行了测试。如果您阅读了许多 cmets,则在最轻微的竞争条件下可能存在文件锁定问题和性能。我会选择具有内置故障处理和容错能力的 Polly .Net 框架...... 我的问题不是关于那个,而是从 HTTPPosted 文件中做的。 怎么样?从根本上说,您正在写入磁盘,并且正在从磁盘读取同一文件。您收到文件锁定错误。你提到了FileAccess
和FileShare
标志来解决这个问题,然后是关于性能的问题,正如我提到的,我的代码和你一样。它表现良好。那么问题是什么? 在 ASP.NET MVC 中将 FileShare.ReadWrite 与 HttpPostedFile 结合使用 - 您必须使用内存、@efaruk 提到的 MQ 或分贝。让我仔细检查一下 doco HttpPostedFile
没有给你那种控制权。
我知道它没有,这就是为什么我从 httpposted 文件中寻求替代方案,甚至举了一个例子。
不,它不支持它:docs.microsoft.com/en-us/dotnet/api/… - 当文件被上传时,不要从文件中读取信号。或者让文件上传一个 2 步过程,他们将其上传到 DataGrid,然后单击一个按钮来处理将合并/更新新/更改值的数据。
【参考方案1】:
问题:
您想要一个“写入:一次,读取:多次”锁假设:
文件很小(平均写入操作为 5000 毫秒) 没有其他写入或读取操作(只有一个具有 2 个功能的程序) 读取文件的次数远多于写入文件的次数解决方案
using System;
using System.IO;
using System.Threading;
using System.Web.Mvc;
namespace ***_56307594.Controllers
public class HomeController : Controller
public ActionResult A()
readFile();
return View();
public ActionResult B()
writeFile();
return View();
private static object writeLock = new Object();
private void readFile()
while (!Monitor.TryEnter(writeLock, 5000)) ; //wait 5000 ms for the writeLock (serializing access)
using (var stream = new FileStream("filePath", FileMode.Open, FileAccess.Read, FileShare.Read))
using (var reader = new StreamReader(stream))
// active read
// xDocument = XDocument.Parse(streamReader.ReadToEnd());
private void writeFile()
lock (writeLock)
FileStream stream = null;
while (stream == null) //wait for the active read
try
stream = new FileStream("filePath", FileMode.Open, FileAccess.ReadWrite, FileShare.None);
catch (IOException)
// will fail if active read becase FileShare.None while (stream == null) will wait
Request.Files[0].InputStream.CopyTo(stream);
// unlock
注意:
-
我没有测试负载或只是在网络服务器上测试解决方案
我只在纸上测试过?
参考:
locking - How long will a C# lock wait, and what if the code crashes during the lock? - Stack Overflow
c# - Deleting files in use - Stack Overflow
multithreading - Is there a way to detect if an object is locked? - Stack Overflow
Implementing Singleton in C# | Microsoft Docs
c# - Using the same lock for multiple methods - Stack Overflow
c# - Write-Once, Read-Many Lock - Stack Overflow
c# lock write once read many - Google Search
FileShare Enum (System.IO) | Microsoft Docs
【讨论】:
Request.Files[0].InputStream.CopyTo(stream);
似乎不在正确的位置
@MikeFlynn ?♀️ 它在锁内,并且在您使用 FileShare.None 获得独占文件访问权限后
变量stream
超出范围,看你的代码
@MikeFlynn 谢谢?,从 While 计算大括号,它看起来不错(可能是因为它看起来超出范围的间距),我希望它会在某种程度上有所帮助
以上是关于在 ASP.NET MVC 中使用 FileShare.ReadWrite 和 HttpPostedFile的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 和 Angularjs 与 ASP.NET MVC 和 Reactjs
在 ASP.NET 中使用 WebAPI 或 MVC 返回 JSON
七天学会ASP.NET MVC ——ASP.NET MVC 数据传递