Domanda

Ho lavorato su questo piccolo pezzo di codice che sembra banale, ma non riesco davvero a vedere dov'è il problema. Le mie funzioni fanno una cosa abbastanza semplice. Apre un file, copia il suo contenuto, sostituisce una stringa all'interno e copia di nuovo nel file originale (una semplice ricerca e sostituisci all'interno di un file di testo). Non sapevo davvero come farlo mentre aggiungo linee al file originale, quindi creo solo una copia del file, (file.temp) copio anche un backup (file.temp) quindi elimino il file originale (file) e copia il file.temp nel file. Ottengo un'eccezione durante l'eliminazione del file. Ecco il codice di esempio:

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

E la relativa eccezione

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)

Normalmente questi errori provengono da flussi di file non chiusi, ma me ne sono occupata. Immagino di aver dimenticato un passo importante ma non riesco a capire dove. Grazie mille per il tuo aiuto,

È stato utile?

Soluzione

Sembra che un processo esterno (AV?) lo stia bloccando, ma non puoi evitare il problema in primo luogo?

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

Altri suggerimenti

Mi rendo conto di essere un po 'in ritardo, ma ancora meglio tardi che mai. Ho avuto problemi simili di recente. Ho usato XMLWriter per aggiornare successivamente il file XML e stavo ricevendo gli stessi errori. Ho trovato la soluzione pulita per questo:

XMLWriter utilizza FileStream sottostante per accedere al file modificato. Il problema è che quando si chiama il metodo XMLWriter.Close () , il flusso sottostante non viene chiuso e blocca il file. Quello che devi fare è creare un'istanza del tuo XMLWriter con le impostazioni e specificare che devi chiudere lo stream sottostante.

Esempio:

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

Spero che sia d'aiuto.

Il codice funziona come meglio posso dire. Vorrei avviare Sysinternals process explorer e scoprire che cosa contiene file aperto. Potrebbe benissimo essere Visual Studio.

Ha funzionato per me.

Ecco il mio codice di prova. Segue l'esecuzione del test:

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>

Dopo aver riscontrato questo errore e non aver trovato nulla sul Web che mi mettesse a posto, ho pensato di aggiungere un altro motivo per ottenere questa eccezione: i percorsi di origine e destinazione nel comando Copia file sono gli stessi. Mi ci è voluto un po 'per capirlo, ma potrebbe essere utile aggiungere codice da qualche parte per generare un'eccezione se i percorsi di origine e destinazione puntano allo stesso file.

Buona fortuna!

Stai eseguendo uno scanner antivirus in tempo reale per caso? In tal caso, potresti provare (temporaneamente) a disabilitarlo per vedere se questo è ciò che sta accedendo al file che stai tentando di eliminare. (Il suggerimento di Chris di utilizzare Sysinternals process explorer è valido).

Prova questo: funziona in ogni caso, se il file non esiste, lo creerà e quindi gli scriverà. E se esiste già, nessun problema si aprirà e gli scriverà:

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

Dopo aver creato un file è necessario forzare lo stream per rilasciare le risorse:

//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();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top