System.IO.IOИсключение:файл, используемый другим процессом

StackOverflow https://stackoverflow.com/questions/1025407

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

Похоже, что внешний процесс (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;
    }
}

Другие советы

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

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

Пример:

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

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

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

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

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

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>

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

Удачи!

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

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

 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(); 
 } 

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

//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();
 System.Drawing.Image FileUploadPhoto = System.Drawing.Image.FromFile(location1);
                                 FileUploadPhoto.Save(location2);
                                 FileUploadPhoto.Dispose();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top