.NET Framework网络共享文件锁定异常问题求助
.NET Framework下SMB共享文件读写锁异常解决方案
测试代码
using System; using System.IO; namespace filetest { class Program { static void Main(string[] args) { string testString = "Test File"; string testFileName = Guid.NewGuid().ToString() + ".txt"; string storagePath = "Z:"; File.WriteAllText(storagePath + "\\" + testFileName, testString); string input = File.ReadAllText(storagePath + "\\" + testFileName); File.Delete(storagePath + "\\" + testFileName); Console.WriteLine("Complete"); Console.ReadKey(); } } }
注:Z:为映射至其他机器或NAS的SMB/CIFS网络驱动器
抛出异常
运行时File.ReadAllText行触发如下异常:
System.IO.IOException: The process cannot access the file 'Z:\4c639f96-12a9-410d-94a0-ffc6392aa85a.txt' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost) at System.IO.File.InternalReadAllText(String path, Encoding encoding, Boolean checkHost) at System.IO.File.ReadAllText(String path) at Switchvox_VM_Handler.Controllers.FaxController.TestWriteStorageLocation(FaxStorage storage) in D:\tfs2017\Switchvox-VM-Handler\Switchvox-VM-Handler\Controllers\FaxController.cs:line 327
已知情况
- 文件可通过记事本打开,但必须重启运行代码的机器才能删除,结束进程无法释放锁
- .NET Framework 4.7、4.72、4.81版本均存在此问题,迁移至.NET 6则无异常
- 尝试过StreamWriter、File.Copy等替代方式,问题依旧;本地驱动器(如C:)操作完全正常,仅SMB/CIFS共享场景出现该问题
无需迁移至.NET 6的解决办法
1. 手动管理文件流,显式指定FileShare权限
避免使用File.WriteAllText/File.ReadAllText这类高层封装方法,手动创建文件流并明确设置共享权限,确保写入操作完成后立即释放文件锁,允许后续读取和删除操作:
string testString = "Test File"; string testFileName = Guid.NewGuid().ToString() + ".txt"; string storagePath = "Z:"; string fullPath = Path.Combine(storagePath, testFileName); // 写入时允许后续读取、写入和删除操作 using (var fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.ReadWriteDelete)) using (var writer = new StreamWriter(fs)) { writer.Write(testString); } // 读取时同样允许其他进程操作文件 using (var fs = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWriteDelete)) using (var reader = new StreamReader(fs)) { string input = reader.ReadToEnd(); } File.Delete(fullPath); Console.WriteLine("Complete"); Console.ReadKey();
2. 调整.NET Framework配置,禁用文件系统缓存
在应用的app.config或web.config中添加运行时配置,修改文件流的实现逻辑,减少SMB共享场景下的缓存导致的锁持有问题:
<configuration> <runtime> <!-- 禁用异步文件流并使用非缓存实现 --> <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyFileStreamImplementation=false;Switch.System.IO.FileStream.DisableAsync=true" /> </runtime> </configuration>
3. 使用UNC路径替代映射驱动器
将映射驱动器Z:替换为UNC路径(例如\\ServerName\SharedFolder),部分场景下映射驱动器的文件系统交互逻辑会引发锁异常,直接使用UNC路径可规避此类问题:
// 替换为UNC路径 string storagePath = @"\\ServerName\SharedFolder"; string fullPath = Path.Combine(storagePath, testFileName);
内容的提问来源于stack exchange,提问作者achaffman
相关产品推荐
相关产品推荐

