C# System.IO.IOException:另一个进程使用的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1025407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:48:29  来源:igfitidea点击:

System.IO.IOException: file used by another process

c#file-ioioioexception

提问by srodriguez

I've been working on this small piece of code that seems trivial but still, i cannot really see where is the problem. My functions do a pretty simple thing. Opens a file, copy its contents, replace a string inside and copy it back to the original file (a simple search and replace inside a text file then). I didn't really know how to do that as I'm adding lines to the original file, so I just create a copy of the file, (file.temp) copy also a backup (file.temp) then delete the original file(file) and copy the file.temp to file. I get an exception while doing the delete of the file. Here is the sample code:

我一直在研究这段看似微不足道的代码,但仍然无法真正看出问题出在哪里。我的函数做了一件非常简单的事情。打开一个文件,复制其内容,替换其中的字符串并将其复制回原始文件(然后在文本文件中进行简单的搜索和替换)。我真的不知道该怎么做,因为我正在向原始文件添加行,所以我只是创建了文件的副本,(file.temp)复制了备份(file.temp)然后删除了原始文件(file) 并将 file.temp 复制到文件。删除文件时出现异常。这是示例代码:

private static bool modifyFile(FileInfo file, string extractedMethod, string modifiedMethod)
    {
        Boolean result = false;
        FileStream fs = new FileStream(file.FullName + ".tmp", FileMode.Create, FileAccess.Write);
        StreamWriter sw = new StreamWriter(fs);

        StreamReader streamreader = file.OpenText();
        String originalPath = file.FullName;
        string input = streamreader.ReadToEnd();
        Console.WriteLine("input : {0}", input);

        String tempString = input.Replace(extractedMethod, modifiedMethod);
        Console.WriteLine("replaced String {0}", tempString);

        try
        {
            sw.Write(tempString);
            sw.Flush();
            sw.Close();
            sw.Dispose();
            fs.Close();
            fs.Dispose();
            streamreader.Close();
            streamreader.Dispose();

            File.Copy(originalPath, originalPath + ".old", true);
            FileInfo newFile = new FileInfo(originalPath + ".tmp");
            File.Delete(originalPath);
            File.Copy(fs., originalPath, true);

            result = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

        return result;
    }`

And the related exception

以及相关的异常

System.IO.IOException: The process cannot access the file 'E:\mypath\myFile.cs' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.Delete(String path)
   at callingMethod.modifyFile(FileInfo file, String extractedMethod, String modifiedMethod)

Normally these errors come from unclosed file streams, but I've taken care of that. I guess I've forgotten an important step but cannot figure out where. Thank you very much for your help,

通常这些错误来自未关闭的文件流,但我已经解决了。我想我忘记了一个重要的步骤,但不知道在哪里。非常感谢您的帮助,

采纳答案by si618

Sounds like an external process (AV?) is locking it, but can't you avoid the problem in the first place?

听起来像一个外部进程(AV?)正在锁定它,但你不能首先避免这个问题吗?

private static bool modifyFile(FileInfo file, string extractedMethod, string modifiedMethod)
{
    try
    {
        string contents = File.ReadAllText(file.FullName);
        Console.WriteLine("input : {0}", contents);
        contents = contents.Replace(extractedMethod, modifiedMethod);
        Console.WriteLine("replaced String {0}", contents);
        File.WriteAllText(file.FullName, contents);
        return true;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        return false;
    }
}

回答by chris.w.mclean

The code works as best I can tell. I would fire up Sysinternals process explorerand find out what is holding the file open. It might very well be Visual Studio.

该代码尽我所能。我会启动Sysinternals 进程资源管理器并找出打开文件的原因。它很可能是 Visual Studio。

回答by Robert Harvey

It worked for me.

它对我有用。

Here is my test code. Test run follows:

这是我的测试代码。试运行如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            FileInfo f = new FileInfo(args[0]);
            bool result = modifyFile(f, args[1],args[2]);
        }
        private static bool modifyFile(FileInfo file, string extractedMethod, string modifiedMethod) 
        { 
            Boolean result = false; 
            FileStream fs = new FileStream(file.FullName + ".tmp", FileMode.Create, FileAccess.Write); 
            StreamWriter sw = new StreamWriter(fs); 
            StreamReader streamreader = file.OpenText(); 
            String originalPath = file.FullName; 
            string input = streamreader.ReadToEnd(); 
            Console.WriteLine("input : {0}", input); 
            String tempString = input.Replace(extractedMethod, modifiedMethod); 
            Console.WriteLine("replaced String {0}", tempString); 
            try 
            { 
                sw.Write(tempString); 
                sw.Flush(); 
                sw.Close(); 
                sw.Dispose(); 
                fs.Close(); 
                fs.Dispose(); 
                streamreader.Close(); 
                streamreader.Dispose(); 
                File.Copy(originalPath, originalPath + ".old", true); 
                FileInfo newFile = new FileInfo(originalPath + ".tmp"); 
                File.Delete(originalPath); 
                File.Copy(originalPath + ".tmp", originalPath, true); 
                result = true; 
            } 
            catch (Exception ex) 
            { 
                Console.WriteLine(ex); 
            } 
            return result; 
        }
    }
}


C:\testarea>ConsoleApplication1.exe file.txt padding testing
input :         <style type="text/css">
        <!--
         #mytable {
          border-collapse: collapse;
          width: 300px;
         }
         #mytable th,
         #mytable td
         {
          border: 1px solid #000;
          padding: 3px;
         }
         #mytable tr.highlight {
          background-color: #eee;
         }
        //-->
        </style>
replaced String         <style type="text/css">
        <!--
         #mytable {
          border-collapse: collapse;
          width: 300px;
         }
         #mytable th,
         #mytable td
         {
          border: 1px solid #000;
          testing: 3px;
         }
         #mytable tr.highlight {
          background-color: #eee;
         }
        //-->
        </style>

回答by Moe Sisko

Are you running a real-time antivirus scanner by any chance ? If so, you could try (temporarily) disabling it to see if that is what is accessing the file you are trying to delete. (Chris' suggestion to use Sysinternals process explorer is a good one).

您是否正在运行实时防病毒扫描程序?如果是这样,您可以尝试(暂时)禁用它以查看是否正在访问您要删除的文件。(Chris 建议使用 Sysinternals 进程浏览器是一个很好的建议)。

回答by roquen

I realize that I is kinda late, but still better late than never. I was having similar problem recently. I used XMLWriterto subsequently update XML file and was receiving the same errors. I found the clean solution for this:

我意识到我有点晚了,但迟到总比不到好。我最近遇到了类似的问题。我曾经XMLWriter随后更新 XML 文件并收到相同的错误。我为此找到了干净的解决方案:

The XMLWriteruses underlying FileStreamto access the modified file. Problem is that when you call XMLWriter.Close()method, the underlying stream doesn't get closed and is locking the file. What you need to do is to instantiate your XMLWriterwith settings and specify that you need that underlying stream closed.

XMLWriter基本用途FileStream访问修改后的文件。问题是,当您调用XMLWriter.Close()方法时,底层流不会关闭并锁定文件。您需要做的是实例化您XMLWriter的设置并指定您需要关闭底层流。

Example:

例子:

XMLWriterSettings settings = new Settings();
settings.CloseOutput = true;
XMLWriter writer = new XMLWriter(filepath, settings);

Hope it helps.

希望能帮助到你。

回答by Alan

After coming across this error and not finding anything on the web that set me right, I thought I'd add another reason for getting this Exception - namely that the source and destination paths in the File Copy command are the same. It took me a while to figure it out, but it may help to add code somewhere to throw an exception if source and destination paths are pointing to the same file.

在遇到这个错误并且没有在网上找到任何让我正确的东西之后,我想我会添加另一个获得这个异常的原因 - 即文件复制命令中的源路径和目标路径是相同的。我花了一段时间才弄明白,但如果源路径和目标路径指向同一个文件,那么在某处添加代码以抛出异常可能会有所帮助。

Good luck!

祝你好运!

回答by PureSilence

Try this: It works in any case, if the file doesn't exists, it will create it and then write to it. And if already exists, no problem it will open and write to it :

试试这个:它在任何情况下都有效,如果文件不存在,它将创建它然后写入它。如果已经存在,没问题它会打开并写入它:

 using (FileStream fs= new FileStream(@"File.txt",FileMode.Create,FileAccess.ReadWrite))
 { 
   fs.close();
 }
 using (StreamWriter sw = new StreamWriter(@"File.txt")) 
 { 
   sw.WriteLine("bla bla bla"); 
   sw.Close(); 
 } 

回答by pradeep

 System.Drawing.Image FileUploadPhoto = System.Drawing.Image.FromFile(location1);
                                 FileUploadPhoto.Save(location2);
                                 FileUploadPhoto.Dispose();

回答by Faisal Arshad

After creating a file you must force the stream to release the resources:

创建文件后,您必须强制流释放资源:

//FSm is stream for creating file on a path//
System.IO.FileStream FS = new System.IO.FileStream(path + fname,
                                                   System.IO.FileMode.Create);
pro.CopyTo(FS);
FS.Dispose();

回答by emo

My reputation being too small to comment an answer, here is my feedback concerning roquen answer (using settings on xmlwriter to force the stream to close): it works perfectly and it made me save a lot of time. roquen's example requires some adjustment, here is the code that works on .NET framework 4.8 :

我的名声太小,无法评论答案,这是我关于 roquen 答案的反馈(使用 xmlwriter 上的设置强制关闭流):它运行良好,让我节省了大量时间。roquen 的示例需要一些调整,这里是适用于 .NET framework 4.8 的代码:

    XmlWriterSettings settings = new XmlWriterSettings();
    settings.CloseOutput = true;
    writer = XmlWriter.Create(stream, settings);