System. IO. IOException: fichier utilisé par un autre processus
J'ai travaillé sur ce petit morceau de code qui semble trivial mais quand même, Je ne peux pas vraiment voir où est le problème. Mes fonctions font une chose assez simple. Ouvre un fichier, copiez son contenu, remplacez une chaîne à l'intérieur et copiez-la dans le fichier d'origine (une recherche simple et remplacez-la dans un fichier texte). Je ne savais pas vraiment comment faire cela car j'ajoute des lignes au fichier original, donc je crée juste une copie du fichier, (fichier.temp) copiez également une sauvegarde (fichier.temp) puis supprimer l'original fichier (fichier) et copiez le fichier.temp au fichier. Je reçois une exception en faisant la suppression du fichier. Voici l'exemple de code:
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;
}`
Et l'exception connexe
System.IO.IOException: The process cannot access the file 'E:mypathmyFile.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)
Normalement, ces erreurs proviennent de flux de fichiers non fermés, mais j'ai pris soin de cela. Je suppose que j'ai oublié une étape importante mais je ne peux pas comprendre où. Merci beaucoup pour votre aide,
9 réponses
Ressemble à un processus externe (AV?) le verrouille, mais ne pouvez-vous pas éviter le problème en premier lieu?
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;
}
}
Je me rends compte que je suis un peu en retard, mais encore mieux tard que jamais. J'ai eu le même problème récemment. J'ai utilisé XMLWriter
pour mettre à jour ultérieurement le fichier XML et recevais les mêmes erreurs. J'ai trouvé la solution propre pour cela:
Le XMLWriter
utilise FileStream
sous-jacent pour accéder au fichier modifié. Le problème est que lorsque vous appelez la méthode XMLWriter.Close()
, le flux sous-jacent ne se ferme pas et verrouille le fichier. Ce que vous devez faire est d'instancier votre XMLWriter
avec les paramètres et spécifiez que vous besoin de ce flux sous-jacent fermé.
Exemple:
XMLWriterSettings settings = new Settings();
settings.CloseOutput = true;
XMLWriter writer = new XMLWriter(filepath, settings);
J'espère que ça aide.
Le code fonctionne du mieux que je peux dire. Je déclencherais Sysinternals process explorer et découvrirais ce qui maintient le fichier ouvert. Il pourrait très bien être Visual Studio.
Après avoir rencontré cette erreur et ne rien trouver sur le web qui m'a donné raison, j'ai pensé ajouter une autre raison pour obtenir cette Exception - à savoir que les chemins source et destination dans la commande File Copy sont les mêmes. Il m'a fallu un certain temps pour le comprendre, mais cela peut aider à ajouter du code quelque part pour lancer une exception si les chemins source et destination pointent vers le même fichier.
Bonne chance!
Ça a marché pour moi.
Voici mon code de test. L'essai suit:
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>
Utilisez - vous un scanner antivirus en temps réel par hasard ? Si c'est le cas, vous pouvez essayer (Temporairement) de le désactiver pour voir si c'est ce qui accède au fichier que vous essayez de supprimer. (La suggestion de Chris d'utiliser Sysinternals process explorer est bonne).
Essayez ceci: cela fonctionne dans tous les cas, si le fichier n'existe pas, il le créera et y écrira ensuite. Et s'il existe déjà, pas de problème, il s'ouvrira et y écrira:
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();
}
Après avoir créé un fichier, vous devez forcer le flux à libérer les ressources:
//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();