2009-06-22 5 views
23

Я работаю над этим небольшим фрагментом кода, который кажется тривиальным, но все же я не могу понять, где проблема. Мои функции делают довольно простую вещь. Открывает файл, копирует его содержимое, заменяет строку внутри и копирует ее обратно в исходный файл (простой поиск и замену внутри текстового файла). Я действительно не знал, как это сделать, добавляя строки к исходному файлу, поэтому я просто создаю копию файла (file.temp), копируя также резервную копию (file.temp), затем удаляю оригинал файл (файл) и скопируйте файл file.temp в файл. Я получаю исключение при удалении файла. Вот пример код:System.IO.IOException: файл, используемый другим процессом

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) 

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

+1

попробуйте установить объект FileInfo прошел к методу null. – TheVillageIdiot

ответ

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; 
    } 
} 
+13

+1 весь комплекс распоряжаться близко, flush streamreader thingy (не используя использование утверждения и т. Д. И т. Д.) Заставляет меня дрожать. это создает простую проблему в бесполезный беспорядок. –

+0

Большое спасибо за этот метод, я согласен, что это гораздо более ясно, чем мой оригинальный. Это решило мою проблему! – srodriguez

+0

Спасибо за это. Я искал ответ на подобную ситуацию. Я уже закрыл XMLWriter, но он все еще выдавал мне ошибку. Как только я положил утверждение внутри try-catch, он прекратил давать мне ошибку. – illinoistim

5

Код работает как можно лучше. Я должен запустить Sysinternals process explorer и узнать, что держит файл открытым. Возможно, это будет Visual Studio.

3

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

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

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

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

18

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

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

Пример:

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

Надеется, что это помогает.

4

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

Удачи вам!

2

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

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

Я не верю, что он работает в любом случае. Например, попробуйте написать файл PDF, открытый Adobe Reader. – nalply

-1
System.Drawing.Image FileUploadPhoto = System.Drawing.Image.FromFile(location1); 
           FileUploadPhoto.Save(location2); 
           FileUploadPhoto.Dispose(); 
+0

Я не вижу, как этот пост можно назвать ответом, если он вообще ничего не объясняет. –

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(); 
+0

FS.Dispose(); освобождает ресурсы –

 Смежные вопросы

  • Нет связанных вопросов^_^