Saltar al contenido

IOException: el proceso no puede acceder al archivo ‘ruta del archivo’ porque está siendo utilizado por otro proceso

La guía paso a paso o código que hallarás en este artículo es la solución más sencilla y válida que hallamos a tus dudas o problema.

Solución:

¿Cual es la causa?

El mensaje de error es bastante claro: está intentando acceder a un archivo y no se puede acceder a él porque otro proceso (o incluso el mismo proceso) está haciendo algo con él (y no permite compartirlo).

depuración

Puede ser bastante fácil de resolver (o bastante difícil de entender), dependiendo de su escenario específico. Veamos algunos.

Su proceso es el único que accede a ese archivo

estas seguro de que otro proceso es su propio proceso. Si sabe que abre ese archivo en otra parte de su programa, primero debe verificar que cierre correctamente el identificador del archivo después de cada uso. Aquí hay un ejemplo de código con este error:

var stream = new FileStream(path, FileAccess.Read);
var reader = new StreamReader(stream);
// Read data from this file, when I'm done I don't need it any more
File.Delete(path); // IOException: file is in use

Afortunadamente FileStream implementos IDisposablepor lo que es fácil envolver todo su código dentro de un using declaración:

using (var stream = File.Open("myfile.txt", FileMode.Open)) 
    // Use stream


// Here stream is not accessible and it has been closed (also if
// an exception is thrown and stack unrolled

Este patrón también garantizará que el archivo no se quede abierto en caso de excepciones (puede ser la razón por la que el archivo está en uso: algo salió mal y nadie lo cerró; consulte esta publicación para ver un ejemplo).

Si todo parece estar bien (está seguro de que siempre cierra todos los archivos que abre, incluso en el caso de excepciones) y tiene varios subprocesos de trabajo, entonces tiene dos opciones: reelaborar su código para serializar el acceso a los archivos (no siempre factible y no siempre deseado) o aplicar un patrón de reintento. Es un patrón bastante común para las operaciones de E/S: intenta hacer algo y, en caso de error, espera y vuelve a intentarlo (¿se preguntó por qué, por ejemplo, Windows Shell tarda un tiempo en informarle que un archivo está en uso? y no se puede borrar?). En C# es bastante fácil de implementar (vea también mejores ejemplos sobre E/S de disco, redes y acceso a bases de datos).

private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;

for (int i=1; i <= NumberOfRetries; ++i) 
    try 
        // Do stuff with file
        break; // When done we can break loop
    
    catch (IOException e) when (i <= NumberOfRetries) 
        // You may check error code to filter some exceptions, not every error
        // can be recovered.
        Thread.Sleep(DelayOnRetry);
    

Tenga en cuenta un error común que vemos muy a menudo en StackOverflow:

var stream = File.Open(path, FileOpen.Read);
var content = File.ReadAllText(path);

En este caso ReadAllText() fallará porque el archivo está en uso (File.Open() en la línea anterior). Abrir el archivo de antemano no solo es innecesario sino también incorrecto. Lo mismo se aplica a todos File funciones que no devuelven un resolver al archivo con el que estás trabajando: File.ReadAllText(), File.WriteAllText(), File.ReadAllLines(), File.WriteAllLines() y otros (como File.AppendAllXyz() funciones) abrirán y cerrarán el archivo por sí mismos.

Su proceso no es el único que accede a ese archivo

Si su proceso no es el único que accede a ese archivo, entonces la interacción puede ser más difícil. UN patrón de reintento ayudará (si nadie más debe abrir el archivo pero lo está, entonces necesita una utilidad como Process Explorer para verificar quién está haciendo qué).

Maneras de evitar

Cuando corresponda, utilice siempre utilizando declaraciones para abrir archivos. Como se dijo en el párrafo anterior, lo ayudará activamente a evitar muchos errores comunes (consulte esta publicación para ver un ejemplo en como no usarlo).

Si es posible, intente decidir quién posee el acceso a un archivo específico y centralice el acceso a través de algunos métodos bien conocidos. Si, por ejemplo, tiene un archivo de datos donde su programa lee y escribe, entonces debe encuadrar todo el código de E/S dentro de una sola clase. Facilitará la depuración (porque siempre puede colocar un punto de interrupción allí y ver quién está haciendo qué) y también será un punto de sincronización (si es necesario) para el acceso múltiple.

No olvide que las operaciones de E/S siempre pueden fallar, un ejemplo común es este:

if (File.Exists(path))
    File.Delete(path);

Si alguien borra el archivo después File.Exists() pero antes File.Delete()entonces lanzará un IOException en un lugar donde erróneamente puede sentirse seguro.

Siempre que sea posible, aplique un patrón de reintentoy si estás usando FileSystemWatcherconsidere posponer la acción (porque recibirá una notificación, pero es posible que una aplicación siga funcionando exclusivamente con ese archivo).

Escenarios avanzados

No siempre es tan fácil, por lo que es posible que deba compartir el acceso con otra persona. Si, por ejemplo, estás leyendo desde el principio y escribiendo hasta el final, tienes al menos dos opciones.

1) compartir lo mismo FileStream con funciones de sincronización adecuadas (porque no es seguro para subprocesos). Vea esto y esta publicación para ver un ejemplo.

2) usar FileShare enumeración para indicar al sistema operativo que permita que otros procesos (u otras partes de su propio proceso) accedan al mismo archivo al mismo tiempo.

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.Read))


En este ejemplo, mostré cómo abrir un archivo para escribir y compartir para leer; tenga en cuenta que cuando la lectura y la escritura se superponen, se obtienen datos indefinidos o no válidos. Es una situación que hay que manejar a la hora de leer. También tenga en cuenta que esto no hace que el acceso a la stream seguro para subprocesos, por lo que este objeto no se puede compartir con varios subprocesos a menos que el acceso esté sincronizado de alguna manera (consulte los enlaces anteriores). Hay otras opciones para compartir disponibles y abren escenarios más complejos. Consulte MSDN para obtener más detalles.

En general norte los procesos pueden leer del mismo archivo todos juntos, pero solo uno debe escribir, en un escenario controlado, incluso puede habilitar escrituras simultáneas, pero esto no se puede generalizar en algunos párrafos de texto dentro de esta respuesta.

Es posible que desbloquear un archivo utilizado por otro proceso? No siempre es seguro y no es tan fácil, pero sí, es posible.

Utilizando Recurso compartido de archivos solucionó mi problema de abrir el archivo incluso si lo abre otro proceso.

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))


Tuve un problema al cargar una imagen y no pude eliminarla y encontré una solución. glhf

//C# .NET
var image = Image.FromFile(filePath);

image.Dispose(); // this removes all resources

//later...

File.Delete(filePath); //now works

valoraciones y comentarios

Si estás de acuerdo, eres capaz de dejar un enunciado acerca de qué le añadirías a este escrito.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *