System.IO.IOException: файл, используемый другим процессом - PullRequest
25 голосов
/ 22 июня 2009

Я работал над этим небольшим фрагментом кода, который кажется тривиальным, но, тем не менее, я не могу понять, в чем проблема. Мои функции делают довольно простую вещь. Открывает файл, копирует его содержимое, заменяет строку внутри и копирует ее обратно в исходный файл (простой поиск и замена внутри текстового файла). Я действительно не знал, как это сделать, так как я добавляю строки в исходный файл, поэтому я просто создаю копию файла (file.temp), копирую также резервную копию (file.temp), затем удаляю исходный файл (файл) и скопируйте файл .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)

Обычно эти ошибки происходят из открытых потоков файлов, но я позаботился об этом. Я думаю, что забыл важный шаг, но не могу понять, где. Большое спасибо за вашу помощь,

Ответы [ 9 ]

24 голосов
/ 22 июня 2009

Похоже, что внешний процесс (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;
    }
}
19 голосов
/ 23 марта 2010

Я понимаю, что я немного опоздал, но все же лучше поздно, чем никогда. У меня недавно была похожая проблема. Я использовал XMLWriter для последующего обновления XML-файла и получал те же ошибки. Я нашел чистое решение для этого:

XMLWriter использует базовый FileStream для доступа к измененному файлу. Проблема в том, что когда вы вызываете метод XMLWriter.Close(), основной поток не закрывается и блокирует файл. Что вам нужно сделать, это создать экземпляр XMLWriter с настройками и указать, что вам нужен этот основной поток закрыт.

Пример:

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

Надеюсь, это поможет.

5 голосов
/ 22 июня 2009

Код работает, насколько я могу судить. Я бы запустил Sysinternals Process Explorer и выяснил, что держит файл открытым. Это вполне может быть Visual Studio.

4 голосов
/ 18 января 2013

После того, как я наткнулся на эту ошибку и не нашел в сети ничего, что меня исправило, я подумал, что добавлю еще одну причину для получения этого исключения, а именно, что исходный и целевой пути в команде File Copy одинаковы. Мне потребовалось некоторое время, чтобы понять это, но это может помочь добавить код куда-нибудь, чтобы вызвать исключение, если пути источника и назначения указывают на один и тот же файл.

Удачи!

4 голосов
/ 22 июня 2009

у меня сработало.

Вот мой тестовый код. Тестовый прогон следующий:

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>
3 голосов
/ 12 февраля 2013

Попробуйте: в любом случае это работает, если файл не существует, он создаст его и затем запишет в него. И если он уже существует, без проблем он откроется и напишет:

 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(); 
 } 
3 голосов
/ 22 июня 2009

Вы случайно запускаете антивирусный сканер в реальном времени? Если это так, вы можете попробовать (временно) отключить его, чтобы увидеть, является ли это доступом к файлу, который вы пытаетесь удалить. (Предложение Криса использовать Sysinternals Process Explorer является хорошим).

0 голосов
/ 02 ноября 2017

После создания файла вы должны заставить поток освободить ресурсы:

//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();
0 голосов
/ 25 июля 2013
 System.Drawing.Image FileUploadPhoto = System.Drawing.Image.FromFile(location1);
                                 FileUploadPhoto.Save(location2);
                                 FileUploadPhoto.Dispose();
...