Pergunta

Eu tenho trabalhado nesse pequeno código que parece trivial, mas ainda assim, não consigo ver onde está o problema. Minhas funções fazem uma coisa bem simples. Abre um arquivo, copie seu conteúdo, substitua uma string dentro e copie -a novamente para o arquivo original (uma pesquisa simples e substitua dentro de um arquivo de texto). Eu realmente não sabia como fazer isso, pois estou adicionando linhas ao arquivo original, então eu apenas crio uma cópia do arquivo, (file.temp) copy também um backup (file.temp) e exclua o arquivo original (arquivo) e copie o arquivo.temp para arquivo. Eu recebo uma exceção ao fazer a exclusão do arquivo. Aqui está o código de exemplo:

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 a exceção relacionada

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, esses erros vêm de fluxos de arquivos não isolados, mas eu cuidei disso. Acho que esqueci um passo importante, mas não consigo descobrir onde. Muito obrigado pela sua ajuda,

Foi útil?

Solução

Parece um processo externo (AV?) Está travando, mas você não pode evitar o problema em primeiro lugar?

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

Outras dicas

Percebo que estou meio tarde, mas ainda melhor tarde do que nunca. Eu estava tendo um problema semelhante recentemente. eu usei XMLWriter Atualizar posteriormente o arquivo XML e estava recebendo os mesmos erros. Eu encontrei a solução limpa para isso:

o XMLWriter usos subjacentes FileStream Para acessar o arquivo modificado. O problema é que quando você liga XMLWriter.Close() Método, o fluxo subjacente não é fechado e está bloqueando o arquivo. O que você precisa fazer é instanciar seu XMLWriter com configurações e especifique que você precisa do fluxo subjacente fechado.

Exemplo:

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

Espero que ajude.

O código funciona da melhor maneira possível. Eu iria demitir SysInternals Process Explorer e descubra o que está segurando o arquivo aberto. Pode muito bem ser o Visual Studio.

Funcionou para mim.

Aqui está o meu código de teste. A execução do teste segue:

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>

Depois de encontrar esse erro e não encontrar nada na web que me acerte, pensei em adicionar outro motivo para obter essa exceção - a saber, que os caminhos de origem e destino no comando de cópia de arquivo são os mesmos. Demorei um pouco para descobrir, mas pode ajudar a adicionar código em algum lugar para lançar uma exceção se os caminhos de origem e destino estão apontando para o mesmo arquivo.

Boa sorte!

Você está executando um scanner antivírus em tempo real por acaso? Nesse caso, você pode tentar (temporariamente) desativá -lo para ver se é isso que está acessando o arquivo que você está tentando excluir. (A sugestão de Chris de usar o SysInternalths Process Explorer é boa).

Tente o seguinte: funciona em qualquer caso, se o arquivo não existir, ele o criará e o escreverá. E se já existir, não há problema, ele abrirá e escreverá para ele:

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

Depois de criar um arquivo, você deve forçar o fluxo para liberar os recursos:

//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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top