Question

J'ai travaillé sur ce petit morceau de code qui semble trivial, mais je ne vois toujours pas vraiment où est le problème. Mes fonctions font une chose assez simple. Ouvre un fichier, copie son contenu, remplace une chaîne à l'intérieur et recopie-le dans le fichier d'origine (une simple recherche et remplacement dans un fichier texte ensuite). Je ne savais pas vraiment comment faire cela car j'ajoutais des lignes au fichier d'origine. Je crée donc simplement une copie du fichier (fichier.temp), copie également une sauvegarde (fichier.temp), puis supprime le fichier d'origine. (fichier) et copiez le fichier.temp dans un fichier. Je reçois une exception lors de 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 associée

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)

Normalement, ces erreurs proviennent de flux de fichiers non fermés, mais je m'en suis occupé. Je suppose que j'ai oublié une étape importante, mais je ne peux pas trouver où. Merci beaucoup pour votre aide,

Était-ce utile?

La solution

Cela ressemble à un processus externe (AV?) qui 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;
    }
}

Autres conseils

Je me rends compte que je suis un peu en retard, mais qu'il vaut mieux tard que jamais. J'avais un problème similaire récemment. J'ai utilisé XMLWriter pour mettre à jour ultérieurement le fichier XML et je recevais les mêmes erreurs. J'ai trouvé la solution propre pour cela:

Le XMLWriter utilise le 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 des paramètres et de spécifier que vous devez fermer ce flux sous-jacent.

Exemple:

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

J'espère que ça aide.

Le code fonctionne comme je peux le dire. Je déclencherais l'explorateur de processus Sysinternals et savoir ce qui se passe fichier ouvert. Ce pourrait très bien être Visual Studio.

Cela a fonctionné pour moi.

Voici mon code de test. Le test 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>

Après être tombé sur cette erreur et ne pas trouver quoi que ce soit sur le Web qui me corrige, j'ai pensé ajouter une autre raison pour obtenir cette exception, à savoir que les chemins source et cible de la commande Copie de fichier sont les mêmes. Il m'a fallu un certain temps pour le comprendre, mais il peut être utile d'ajouter du code quelque part pour générer une exception si les chemins source et de destination pointent vers le même fichier.

Bonne chance!

Utilisez-vous un analyseur 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 l'explorateur de processus Sysinternals en est une bonne).

Essayez ceci: Dans tous les cas, cela fonctionne. Si le fichier n’existe pas, il le créera puis l’écrira. Et si cela 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();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top