c# - siendo - System.IO.IOException: archivo utilizado por otro proceso
archivo ocupado por otro proceso (9)
¿Está ejecutando un escáner de antivirus en tiempo real por casualidad? De ser así, podría intentar (temporalmente) desactivarlo para ver si eso es lo que está accediendo al archivo que está tratando de eliminar. (La sugerencia de Chris de utilizar Sysinternals Process Explorer es buena).
He estado trabajando en este pequeño fragmento de código que parece trivial, pero aún así, no puedo ver dónde está el problema. Mis funciones son bastante simples. Abre un archivo, copia su contenido, reemplaza una cadena adentro y la copia al archivo original (una simple búsqueda y luego reemplaza dentro de un archivo de texto). Realmente no sabía cómo hacerlo ya que estoy agregando líneas al archivo original, así que solo creo una copia del archivo, (file.temp) copio también una copia de seguridad (file.temp) y luego borro el archivo original (archivo) y copie el archivo.temp al archivo. Obtengo una excepción mientras hago la eliminación del archivo. Aquí está el código de ejemplo:
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;
}`
Y la excepción 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 estos errores provienen de flujos de archivos no cerrados, pero me he encargado de eso. Supongo que olvidé un paso importante pero no sé dónde. Muchas gracias por su ayuda,
¿Suena como un proceso externo (AV?) Lo está bloqueando, pero ¿no puedes evitar el problema en primer 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;
}
}
Después de crear un archivo, debe forzar la transmisión para que libere los 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();
Después de encontrar este error y no encontrar nada en la web que me haya configurado correctamente, pensé que agregaría otra razón para obtener esta Excepción, es decir, que las rutas de origen y de destino en el comando Copiar archivo son las mismas. Me tomó un tiempo darme cuenta, pero puede ser útil agregar código en alguna parte para lanzar una excepción si las rutas de origen y de destino apuntan al mismo archivo.
¡Buena suerte!
El código funciona lo mejor que puedo decir. Arrancaría el explorador de procesos de Sysinternals y descubriría qué es lo que mantiene abierto el archivo. Puede ser que sea Visual Studio.
Funcionó para mí
Aquí está mi código de prueba. Prueba de ejecución sigue:
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>
Intente esto: funciona en cualquier caso, si el archivo no existe, lo creará y luego escribirá en él. Y si ya existe, no hay problema, se abrirá y escribirá en él:
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();
}
Me doy cuenta de que estoy un poco tarde, pero aún mejor tarde que nunca. Estaba teniendo un problema similar recientemente. XMLWriter
para actualizar posteriormente el archivo XML y recibía los mismos errores. Encontré la solución limpia para esto:
XMLWriter
utiliza FileStream
subyacente para acceder al archivo modificado. El problema es que cuando llamas XMLWriter.Close()
método XMLWriter.Close()
, la transmisión subyacente no se cierra y bloquea el archivo. Lo que necesita hacer es crear una instancia de su XMLWriter
con la configuración y especificar que necesita que la secuencia subyacente se cierre.
Ejemplo:
XMLWriterSettings settings = new Settings();
settings.CloseOutput = true;
XMLWriter writer = new XMLWriter(filepath, settings);
Espero eso ayude.
System.Drawing.Image FileUploadPhoto = System.Drawing.Image.FromFile(location1);
FileUploadPhoto.Save(location2);
FileUploadPhoto.Dispose();