26

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

以及相关的异常

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)

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

4

10 回答 10

23

听起来像一个外部进程(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;
    }
}
于 2009-06-22T04:27:29.630 回答
19

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

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

例子:

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

希望能帮助到你。

于 2010-03-23T11:46:22.980 回答
5

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

于 2009-06-22T03:59:18.823 回答
4

它对我有用。

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

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>
于 2009-06-22T04:10:07.377 回答
4

在遇到这个错误并且在网络上没有找到任何让我正确的东西之后,我想我会添加另一个导致此异常的原因 - 即文件复制命令中的源路径和目标路径是相同的。我花了一段时间才弄清楚,但如果源路径和目标路径指向同一个文件,它可能有助于在某处添加代码以引发异常。

祝你好运!

于 2013-01-17T22:59:10.653 回答
3

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

于 2009-06-22T04:23:46.053 回答
3

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

 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(); 
 } 
于 2013-02-12T10:41:17.283 回答
0

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

//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();
于 2017-11-02T07:57:32.737 回答
0

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

    XmlWriterSettings settings = new XmlWriterSettings();
    settings.CloseOutput = true;
    writer = XmlWriter.Create(stream, settings);
于 2019-11-21T10:13:16.517 回答
-1
 System.Drawing.Image FileUploadPhoto = System.Drawing.Image.FromFile(location1);
                                 FileUploadPhoto.Save(location2);
                                 FileUploadPhoto.Dispose();
于 2013-07-25T06:32:33.873 回答