2009-06-22 4 views
23

Ich habe an diesem kleinen Stück Code gearbeitet, der trivial erscheint, aber immer noch, ich kann nicht wirklich sehen, wo das Problem ist. Meine Funktionen machen eine ziemlich einfache Sache. Öffnet eine Datei, kopiert ihren Inhalt, ersetzt eine Zeichenkette und kopiert sie zurück in die Originaldatei (einfaches Suchen und Ersetzen in einer Textdatei). Ich wusste nicht wirklich, wie das geht, da ich der Originaldatei Zeilen hinzufüge, also erstelle ich einfach eine Kopie der Datei (file.temp) kopiere auch eine Sicherungskopie (file.temp) und lösche dann das Original Datei (Datei) und kopieren Sie die Datei.temp in Datei. Ich bekomme eine Ausnahme beim Löschen der Datei. Hier ist der Beispielcode:System.IO.IOException: Datei von einem anderen Prozess

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; 
    }` 

und die damit verbundene Ausnahme

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) 

diese Fehler kommen aus unverschlossenen Dateiströme Normalerweise, aber ich habe davon gesorgt. Ich denke, ich habe einen wichtigen Schritt vergessen, kann aber nicht herausfinden, wo. Vielen Dank für Ihre Hilfe,

+1

versuchen Fileinfo-Objekt übergeben Einstellung zur Methode auf Null setzen. – TheVillageIdiot

Antwort

23

Klingt wie ein externer Prozess (AV?) Ist es sperren, aber können Sie das Problem in erster Linie vermeiden?

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 der gesamte Komplex zu entsorgen, flush streamreader thingy (nicht mit Anweisung usw. etc ..) macht mich zittern. Es macht ein einfaches Problem zu einem unhaltbaren Chaos. –

+0

Vielen Dank für diese Methode, ich stimme zu, dass es auf diese Weise viel klarer ist als meine ursprüngliche. Das hat mein Problem gelöst! – srodriguez

+0

Vielen Dank dafür. Ich hatte nach einer Antwort für eine ähnliche Situation gesucht. Ich hatte den XMLWriter bereits geschlossen, aber es gab mir immer noch den Fehler. Sobald ich die Anweisung in einen try-catch gesetzt hatte, hörte es auf, mir den Fehler zu geben. – illinoistim

5

Der Code funktioniert so gut ich kann sagen. Ich würde Sysinternals process explorer auslösen und herausfinden, was die Datei geöffnet hält. Es könnte sehr gut Visual Studio sein.

3

Es funktionierte für mich.

Hier ist mein Testcode. Testlauf folgt:

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

Führen Sie zufällig einen Echtzeit-Antivirus-Scanner? Wenn ja, könnten Sie versuchen (vorübergehend), es zu deaktivieren, um zu sehen, ob auf die Datei zugegriffen wird, die Sie löschen möchten. (Chris Vorschlag, Sysinternals Process Explorer zu verwenden, ist ein guter).

18

Ich erkenne, dass ich ein bisschen spät bin, aber immer noch besser spät als nie. Ich hatte kürzlich ein ähnliches Problem. Ich habe XMLWriter verwendet, um die XML-Datei nachträglich zu aktualisieren und erhielt die gleichen Fehler. Ich fand die saubere Lösung dafür:

Die XMLWriter verwendet zugrunde liegenden FileStream, um auf die geänderte Datei zuzugreifen. Problem ist, dass beim Aufruf der Methode XMLWriter.Close() der zugrunde liegende Stream nicht geschlossen wird und die Datei gesperrt wird. Was Sie tun müssen, ist Instanziieren Sie Ihre XMLWriter mit Einstellungen und geben Sie an, dass Sie diesen zugrunde liegenden Stream geschlossen benötigen.

Beispiel:

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

Hoffe, es hilft.

4

Nach über diesen Fehler kommen und nicht im Web zu finden, etwas, das mich richtig gesetzt ist, dachte ich, ich einen anderen Grund für immer diese Ausnahme hinzufügen würde - nämlich, dass die Quell- und Zielpfade in der Datei kopieren Befehl gleich sind. Es dauerte eine Weile, um es herauszufinden, aber es kann Code hinzufügen helfen irgendwo eine Ausnahme zu werfen, wenn Quell- und Zielpfade in die gleiche Datei verweisen.

Viel Glück!

2

Versuchen Sie Folgendes: Es funktioniert in jedem Fall, wenn die Datei nicht existiert, wird es erstellen und dann darauf schreiben. Und wenn bereits vorhanden ist, wird kein Problem es öffnen und schreiben, um es:

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

Ich glaube dir nicht, dass es auf jeden Fall funktioniert. Versuchen Sie beispielsweise, in eine PDF-Datei zu schreiben, die von Adobe Reader geöffnet ist. – nalply

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

Ich kann nicht sehen, wie dieser Beitrag als Antwort bezeichnet werden kann, wenn er überhaupt nichts erklärt. –

0

Nach Erstellen einer Datei müssen Sie den Strom zwingen, die Ressourcen freizugeben:

//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(); gibt die Ressourcen frei –