移动大体积Zip文件时持续抛出System.IO.IOException问题求助
移动共享文件夹中大体积ZIP文件时抛出“文件被其他进程占用”IOException
我是编程新手,这是首次提问。我的程序负责在服务器不同磁盘间移动各类文件,处理小文件时一切正常,但移动10-20GB的大体积Zip文件时,总会抛出如下异常:
System.IO.IOException: The process cannot access the file because it is being used by another process. at System.IO.FileSystem.MoveFile(String sourceFullPath, String destFullPath, Boolean overwrite) at System.IO.FileInfo.MoveTo(String destFileName, Boolean overwrite) at MPOS_Archiver.Program.Main(String[] args) in C:\Users\ivan.gazic\Desktop\MPOS_Archiver\MPOS_Archiver\Program.cs:line 106
补充说明:这些文件是同事放在磁盘共享文件夹中的,我仅执行移动操作,代码中没有打开FileStream,不存在未关闭流的情况。实现文件移动的代码如下:
files = Directory.GetFiles(Path.Combine(sourcePath, bkz)).ToArray(); if (files.Length > 0) { foreach (string file in files) { FileInfo dbZIPfile = new FileInfo(file); try { dbZIPfile.MoveTo(Path.Combine(targetPath, bkz, dbZIPfile.Name), true); } catch (IOException ex) { Console.WriteLine("There was an error moving the DB ZIP: " + ex); } Console.WriteLine("File " + dbZIPfile.Name + " moved to " + Path.Combine(targetPath, bkz)); } } else { Console.WriteLine("No DB .ZIP in market" + bkz); }
恳请帮忙排查问题原因。
排查方向与解决建议
1. 文件未完成上传
大文件上传到共享文件夹需要较长时间,如果你在同事还没传完时就触发移动,文件会被上传进程(比如Windows文件复制、FTP服务)占用。小文件传输快,所以不会触发这个问题。
解决办法:
- 增加文件稳定性检查:比如连续两次读取文件大小,间隔几秒,如果大小一致再尝试移动;
- 约定上传标记:让同事上传完成后给文件加后缀(比如
.ready),程序只处理带标记的文件; - 增加重试逻辑,遇到占用错误时等待一段时间再重试。
2. 杀毒/安全软件扫描
服务器上的杀毒软件、EDR工具会对大文件做实时扫描,扫描过程中文件会被锁定。
解决办法:
- 查看杀毒软件日志,确认是否是它在占用文件;
- 临时将共享文件夹和目标文件夹加入杀毒软件排除列表,测试是否解决问题;
- 调整扫描策略,避免在业务高峰期扫描大文件。
3. 共享文件夹的其他会话占用
可能有其他用户或进程在访问该文件:比如同事的资源管理器还打开着这个文件,或者有其他服务在读取共享文件夹中的文件。
解决办法:
- 在服务器上打开「计算机管理」→「共享文件夹」→「打开文件」,查看是否有会话在占用目标文件;
- 通知相关用户关闭文件或断开共享连接后再尝试移动。
4. 系统后台进程占用
Windows的索引服务、超级预读取等后台进程可能会访问大文件,导致文件被锁定。
解决办法:
- 临时关闭Windows搜索服务(
WSearch),测试是否解决问题; - 给移动操作增加重试机制,优化后的代码示例:
using System.Threading; // ... files = Directory.GetFiles(Path.Combine(sourcePath, bkz)).ToArray(); if (files.Length > 0) { int maxRetries = 3; int retryDelayMs = 3000; // 每次重试间隔3秒 foreach (string file in files) { FileInfo dbZIPfile = new FileInfo(file); bool moveSuccess = false; int retryCount = 0; while (retryCount < maxRetries && !moveSuccess) { try { // 先尝试独占打开文件,验证是否被占用 using (var stream = dbZIPfile.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { // 能打开说明文件未被占用 } dbZIPfile.MoveTo(Path.Combine(targetPath, bkz, dbZIPfile.Name), true); moveSuccess = true; Console.WriteLine($"File {dbZIPfile.Name} moved to {Path.Combine(targetPath, bkz)}"); } catch (IOException ex) { retryCount++; Console.WriteLine($"Move attempt {retryCount} failed: {ex.Message}"); if (retryCount < maxRetries) { Console.WriteLine($"Retrying in {retryDelayMs / 1000} seconds..."); Thread.Sleep(retryDelayMs); } else { Console.WriteLine($"Failed to move {dbZIPfile.Name} after {maxRetries} attempts"); } } } } } else { Console.WriteLine("No DB .ZIP in market" + bkz); }
内容的提问来源于stack exchange,提问作者L8 ReaperX
相关产品推荐
相关产品推荐

