在代码中移动文件后文件锁定错误

Posted

技术标签:

【中文标题】在代码中移动文件后文件锁定错误【英文标题】:File lock errors after moving files in code 【发布时间】:2016-11-20 22:57:30 【问题描述】:

我正在使用以下代码将文件移动到文件夹中

File.Move(Source,Dest);

然后我尝试在下一个方法中打开并读取文件,但我一直因进程错误而锁定文件。

所以我把文件改成下面的代码

public async static Task<bool> MoveFileAsync(string sourceFileName, string destinationFileName)

    using(FileStream sourceStream = File.Open(sourceFileName, FileMode.Open))
    
        using(FileStream destinationStream = File.Create(destinationFileName))
        
            try
            
                await sourceStream.CopyToAsync(destinationStream);
                File.Delete(sourceFileName);
                return true;
            
            catch
            
                return false;
            
        
    

我不断收到文件被锁定的错误

关于如何防止这种情况发生的任何想法。

这都是使用 FileSystemWatcher 来监视文件夹...代码如下。我可以确认当我将文件拖放到文件夹中时不会发生这些错误......即使我拖动多个文件...... 使用系统; 使用 System.Collections.Generic; 使用 System.IO; 使用 System.Linq; 使用 System.Text; 使用 System.Threading.Tasks;

namespace DocumentManager.RepositoryService

    internal class MonitorDropFolder
    
        public string RepositoryPath  get; set; 
        public FileSystemWatcher Watcher  get; set; 

        public MonitorDropFolder ()
        
            Watcher = new FileSystemWatcher();
            Watcher.Path = @"c:\Repository\DropLocation";
            Watcher.NotifyFilter = NotifyFilters.FileName;
            Watcher.Filter = "*.docx";
            Watcher.Created += new FileSystemEventHandler(OnCreatedHandler);

            StartMonitoring();
        

        public void StartMonitoring()
        
            Watcher.EnableRaisingEvents = true;
        

        public void StopMonitoring()
        
            Watcher.EnableRaisingEvents = false;
        

        private void OnCreatedHandler(object source, FileSystemEventArgs e)
         
            if(e.ChangeType == WatcherChangeTypes.Created)
            
                //don't process temporary files
                if (Path.GetFileName(e.FullPath).Substring(0, 1) == "~" || Path.GetFileName(e.FullPath).Substring(0, 1) == "$")
                    return;


                var result = convert(e.FullPath, GetDocStatus(e.Name)).Result;
                FileService.MoveNativeToDraft(e.FullPath);
            
        

        private async Task<bool> convert(string fileName, string docStatus)
        
            try
            
                ConvertWordToPDF convertor = new ConvertWordToPDF();
                var task = Task.Run(()=>convertor.Convert(fileName, docStatus));
                await task;


                return true;
            
            catch (Exception)
            
                return false;
            
        
    

提前致谢

更新: 我是这样调用代码的……

public static void MoveIntoRepository(string sourceFile)

    string destinationDir = @"C:\Repository\DropLocation\";
    var result = MoveFileAsync(sourceFile, Path.Combine(destinationDir, Path.GetFileName(sourceFile))).Result;

我也尝试过像这样绕过文件锁......

bool isFileLocked = isLocked(filename);
int numTries = 0;
while(isFileLocked)

    numTries++;
    if (numTries > 100)
        throw new Exception("FileLock Error");

    ///the following is actually in a called method
    byte[] byteArray = File.ReadAllBytes(filename);
    ///... rest of code here

    Thread.Sleep(500);
    isFileLocked = isLocked(filename);

调用这个方法

private static bool isLocked(string filename)

    try 
               
        FileStream st = new FileStream();
        st = File.Open(filename,FileMode.Open);
        st.Close();
        return false;
    
    catch (Exception)
    
        return true;
        throw;
    

【问题讨论】:

如果您使用 fsw 来检测文件更改,那么您很可能在操作系统或其他程序正在使用该文件时尝试访问该文件。 File.Move 只会在复制操作期间锁定文件,并且只有目标文件,源文件被共享以供读取。 另外,如果您调用 MoveFileAsync 函数,您还没有发布代码,这可能是错误所在,请将其添加到问题中。 【参考方案1】:

在下面的代码中查看我的 cmets:

using(FileStream sourceStream = File.Open(sourceFileName, FileMode.Open))

    using(FileStream destinationStream = File.Create(destinationFileName))
    
        try
        
            await sourceStream.CopyToAsync(destinationStream);
            // The sourceFileName file is locked since you are inside the 
            // the using statement. Move statement for deleting file to
            // outside the using.
            File.Delete(sourceFileName);
            return true;
        
        catch
        
            return false;
        
    

// Move it here

【讨论】:

以上是关于在代码中移动文件后文件锁定错误的主要内容,如果未能解决你的问题,请参考以下文章

myProject 已锁定编辑,您可能无法保存更改?

Sevenzipsharp 文件锁。我不能移动文件?

移动硬盘无法新建文件夹怎么修复?

Win7移动硬盘无法存入文件,提示错误代码:0x80070570

将其移动到资源文件夹后在handsontable上出现404

EBUSY:资源繁忙或锁定,重命名。