none
Desbloquear archivo utilizado

    Question

  • buenos dias, hace unos dias cree un programilla de consola para descargar un archivo a una carpeta en local, el problema que me estoy encontrando es que dicho archivo se me queda bloqueado y me dice que lo esta utilizando el programa, entonces no me deja actualizar dicho fichero, no se por que me pasa esto, el programa descarga tres archivos y solo pasa con uno de ellos, alguna idea de como puedo solucionarlo, o creando algo para que me tenga desbloqueado cuando el programa lo descargue?.

     

    muchas gracias

    un saludo

    Thursday, April 29, 2010 9:32 AM

Answers

  • Muy extraño, pero creo que la solución sigue siendo esa,

    segun analizo, la primera descarga falla, luego en el catch haces un reintento pero ahí te falla porque dice que el archivo ya esta siendo usado... y claro que esta siendo usado porque como la descarga fallo la primera vez al procesar la excepción no estas liberando bien los recursos, es más en ese finally te salta la excepción de nuevo al no poder hacer Close de un stream dado que su stream base ya fue cerrado.

    mira modifica el orden de este segmento:

     

     finally
     {
      // Close streams
      stream.Close();
      reader.Close();
      writer.Close();
    
     }

     

     dejalo así, cierras primero los streams dependientes y al final los no dependientes, también validas cuales objetos han sido inicializados, y finalmente cambias el scope de las declaraciones para facilitar atrapar la excepión en cascada cuando se requiera.

     

     public FtpStatusCode Download(string destinationFile, Uri downloadUri, string userName, string password)
     {
      Stream stream = null;
      StreamReader reader = null;
      StreamWriter writer = null;
    
      try
      {
      // Check if the URI is and FTP site
      if (downloadUri.Scheme != Uri.UriSchemeFtp)
      {
       throw new ArgumentException("Invalid FTP site");
      }
    
      // Set up the request
      FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(downloadUri);
      // Credentials for FTP URI
      ftpRequest.Credentials = new NetworkCredential(userName, password);
      // Set method as file download.
      ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
      // get the response object
      FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
      
      // get the file as a stream from the response object and write it as a file stream to the local disk
      try
      {
       stream = ftpResponse.GetResponseStream();
       reader = new StreamReader(stream, Encoding.UTF8);
       writer = new StreamWriter(destinationFile, false);
       writer.Write(reader.ReadToEnd());
       return ftpResponse.StatusCode;
      }
      finally
      {
       // Close streams
       if (writer != null)
       writer.Close();
       if (reader != null)
       reader.Close();
       if (stream != null)
       stream.Close();
      }
      }
      catch (Exception ex)
      {
    #if DEBUG
      MessageBox.Show("Eror:"+ ex.ToString());
    #endif
      throw ex;
      }
     }

     

    Si despues de esto sigues con los problemas te sugiero 3 cosas:

    1- utiliza el Process Monitor de windows internals

    2- hasle windbg

    3- pasanos la solución para revisarla

     

    saludos


    Juan Carlos Ruiz
    Microsoft MVP - Visual C#
    Visita mi blog:

    Ideas de Un Conejo - http://juank.black-byte.com

    Tuesday, May 04, 2010 2:45 PM
    Moderator

All replies

  • Este tipo de cosas pasan cuando se te olvida hacer el Close o el Dispose del objeto que está leyendo el fichero. Convendría revisar el código que estás usando, a ver si se puede dar alguna circunstancia en la que se te "escape" la secuencia de ejecución sin haber cerrado lo que ha abierto.

     

    Thursday, April 29, 2010 10:43 AM
    Moderator
  • hola

    cuando dices "para descargar un archivo a una carpeta en local", has valdiado en el codigo que los objetos que operan con el archivo sean corectamente destruidos ?

    como recomendacion peudo decirte que el uso del bloque "using" ayuda mucho

    mira este ejemplo

    How to: Write Text to a File

    no se si es lo mismo que tu usas, pero alli veras el ejemplo del uso del using, esto aseguroa la descruccion del objeto, y evita justamente que quede al archivo lockeado

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Thursday, April 29, 2010 12:09 PM
  • Mirar, este es el codigo que utilizo para descargar estos archivos, el que me da problemas es el primero. yo lo eh mirado y no eh visto nada, nose, tal vez sea el otro programa que lee el archivo, no se... seguire mirando a ver si encuentro el problema.

     

     #region descargas de los nodos
          //Desacarga nodo del concentrador 1
          Console.WriteLine("Iniciando la conexion al concentrador del trafo 1 ftp://10.255.0.91");
            
        try
    
        {
           Console.WriteLine("Iniciando la descarga del fichero (nodos.xml)");
           
           FtpStatusCode retunVal = Download("S:\\Camping/1/nodos.xml", new Uri("ftp://10.255.0.91/config/nodos.xml"), "concentrador", "445oqta");
        }
        catch (Exception)
        {
         Console.WriteLine("La descarga a fallado " + DateTime.Now.ToString());
    
         Console.WriteLine("Gestor intentara descargar el fichero ");
         try
         {
           FtpStatusCode retunVal = Download("S:\\Camping/1/nodos.xml", new Uri("ftp://10.255.0.91/config/nodos.xml"), "concentrador", "445oqta");
         }
         catch
         {
           Console.WriteLine("Imposible descargar el archivo (nodos.xml), mande un e-mail a sistemas@aseprel.com");
           
           
         }
        }
    
        Console.WriteLine("Descarga del fichero (nodos.xml) en el trafo 1 completa " + DateTime.Now.ToString());
    
    
    
    
    
    
          //Desacarga nodo del concentrador 2
        Console.WriteLine("Iniciando la conexion al concentrador del trafo 2 ftp://10.255.0.92");
    
         try
         {
           Console.WriteLine("Iniciando la descarga del fichero (nodos.xml)");
    
           FtpStatusCode retunVal = Download("S:\\Camping/2/nodos.xml", new Uri("ftp://10.255.0.92/config/nodos.xml"), "concentrador", "445oqta");
         }
         catch (Exception)
         {
           Console.WriteLine("La descarga a fallado " + DateTime.Now.ToString());
    
           Console.WriteLine("Gestor intentara descargar el fichero ");
           try
           {
             FtpStatusCode retunVal = Download("S:\\Camping/2/nodos.xml", new Uri("ftp://10.255.0.92/config/nodos.xml"), "concentrador", "445oqta");
           }
           catch
           {
             Console.WriteLine("Imposible descargar el archivo (nodos.xml), mande un e-mail a sistemas@aseprel.com");
             
           }
         }
    
         Console.WriteLine("Descarga del fichero (nodos.xml) en el trafo 2 completa " + DateTime.Now.ToString());
    
    
    
    
    
    
    
         //Desacarga nodo del concentrador 3
         Console.WriteLine("Iniciando la conexion al concentrador del trafo 3 ftp://10.255.0.93");
    
         try
         {
           Console.WriteLine("Iniciando la descarga del fichero (nodos.xml)");
    
           FtpStatusCode retunVal = Download("S:\\Camping/3/nodos.xml", new Uri("ftp://10.255.0.93/config/nodos.xml"), "concentrador", "445oqta");
         }
         catch (Exception)
         {
           Console.WriteLine("La descarga a fallado " + DateTime.Now.ToString());
    
           Console.WriteLine("Gestor intentara descargar el fichero ");
           try
           {
             FtpStatusCode retunVal = Download("S:\\Camping/3/nodos.xml", new Uri("ftp://10.255.0.93/config/nodos.xml"), "concentrador", "445oqta");
           }
           catch
           {
             Console.WriteLine("Imposible descargar el archivo (nodos.xml), mande un e-mail a sistemas@aseprel.com");
             
           }
         }
    
         Console.WriteLine("Descarga del fichero (nodos.xml) en el trafo 3 completa " + DateTime.Now.ToString());
          #endregion

    muchas gracias

    un saludo

    Thursday, April 29, 2010 3:33 PM
  • El código que aquí interesa investigar es el de la función Download porque es quien maneja el fichero.
    Thursday, April 29, 2010 3:38 PM
  • hola

    el tema es que seguramente el problema este dentro del metodo Download()

    este metodo lo has programado tu mismo ?

    has analizado el codigo de este metodo ? alli es donde debes revisar sino se lockea el archivo

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    Thursday, April 29, 2010 3:48 PM
  • Buenos dias pongo el metodo.

     #region metodo ftp
        public FtpStatusCode Download(string destinationFile, Uri downloadUri, string userName, string password)
        {
    
          try
          {
    
            // Check if the URI is and FTP site
    
            if (downloadUri.Scheme != Uri.UriSchemeFtp)
            {
    
              throw new ArgumentException("Invalid FTP site");
    
            }
    
            // Set up the request
    
            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(downloadUri);
    
            // Credentials for FTP URI
    
            ftpRequest.Credentials = new NetworkCredential(userName, password);
    
            // Set method as file download.
    
            ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
    
            // get the response object
    
            FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
    
    
    
            Stream stream = null;
    
            StreamReader reader = null;
    
            StreamWriter writer = null;
    
            // get the file as a stream from the response object and write it as a file stream to the local disk
    
            try
            {
    
              stream = ftpResponse.GetResponseStream();
    
              reader = new StreamReader(stream, Encoding.UTF8);
    
              writer = new StreamWriter(destinationFile, false);
    
              writer.Write(reader.ReadToEnd());
    
              return ftpResponse.StatusCode;
    
            }
    
            finally
            {
    
              // Close streams
    
              stream.Close();
    
              reader.Close();
    
              writer.Close();
    
            }
    
          }
    
          catch (Exception ex)
          {
    
            throw ex;
    
          }
    
        }
        #endregion

    Muchas gracias 

    Un saludo

    Friday, April 30, 2010 6:58 AM
  • tambien tengo este codigo que utiliza el fichero, tal vez sea este, no hago la mas minima.

     

     public string leer(string RutaServer, string ParcelaServidor)
      {
    
       int cont0 = 0;
       int cont1 = 0;
    
       string[] LecturaContador;
       LecturaContador = new string[10];
       XmlDocument doc = new XmlDocument();
    
       doc.Load(RutaServer);
    
       XmlNodeList Fichero = doc.GetElementsByTagName("Nodos");
       XmlNodeList ListaNodos = ((XmlElement)Fichero[0]).GetElementsByTagName("Nodo");
       foreach (XmlElement nodo in ListaNodos)
       {
        cont0++;
        object contador = nodo.GetAttribute("s");
        contador.ToString();
        if (ParcelaServidor.Equals(contador))
        
        {
         XmlNodeList ListaNodos1 = ((XmlElement)Fichero[0]).GetElementsByTagName("En");
         foreach (XmlElement nodo1 in ListaNodos1)
         {
    
          if (cont1 < cont0)
          {
           cont1++;
           string lectura = nodo1.GetAttribute("E0");
           LecturaContador[0] = lectura;
    
          }
    
         }
        }
       }
       return LecturaContador[0];
    
    
      }
    
    un saludo

     

    Friday, April 30, 2010 11:30 AM



  • finally
    {

    // Close streams

    stream.Close();

    reader.Close();

    writer.Close();

    }


     

    El uso de los streams lo podrias meter en un using, aunque en realidad es lo mismo que un try/finally con los Dispose.

     

    Yo te recomendaría que lo modificaras a esto otro:

       finally
        {
    
         // Close streams
    
         if (stream!=null)
            stream.Dispose();
    
         if (reader!=null)
            reader.Close();
    
         if (writer!=null)
            writer.Close();
    
        }

    De todas maneras el fallo no viene de ahí, sino que viene de la función leer. Si te das cuenta cargas el fichero con el Load pero luego ni lo cierras ni lo liberas ni nada. Prueba a encapsular el objeto XMLDocument en un Using para asegurarte que es liberado al salir de ahí. Te quedaría algo así:

        public string leer(string RutaServer, string ParcelaServidor)
        {
    
          int cont0 = 0;
          int cont1 = 0;
    
          string[] LecturaContador;
          LecturaContador = new string[10];
          using (XmlDocument doc = new XmlDocument())
          {
            doc.Load(RutaServer);
    
            XmlNodeList Fichero = doc.GetElementsByTagName("Nodos");
            XmlNodeList ListaNodos = ((XmlElement)Fichero[0]).GetElementsByTagName("Nodo");
            foreach (XmlElement nodo in ListaNodos)
            {
              cont0++;
              object contador = nodo.GetAttribute("s");
              contador.ToString();
              if (ParcelaServidor.Equals(contador))
              {
                XmlNodeList ListaNodos1 = ((XmlElement)Fichero[0]).GetElementsByTagName("En");
                foreach (XmlElement nodo1 in ListaNodos1)
                {
    
                  if (cont1 < cont0)
                  {
                    cont1++;
                    string lectura = nodo1.GetAttribute("E0");
                    LecturaContador[0] = lectura;
    
                  }
    
                }
              }
            }
          }
          return LecturaContador[0];
        }

    Friday, April 30, 2010 2:11 PM
  • hola, tal como me comentas me lanza un error:

     

    System.Xml.XmlDocument': el tipo utilizado en una instrucción using debe poderse convertir implícitamente en 'System.IDisposable'

     

     

    Muchas gracias

     

    un saludo

    Friday, April 30, 2010 3:47 PM
  • Buenos dias, me sigue lanzando el error que indico, intente de otras formas, pero no encuentro la solucion, algun consejo?, 

     

    muchas gracias

    un saludo

    Tuesday, May 04, 2010 8:10 AM
  • Este tipo de cosas pasan cuando se te olvida hacer el Close o el Dispose del objeto que está leyendo el fichero. Convendría revisar el código que estás usando, a ver si se puede dar alguna circunstancia en la que se te "escape" la secuencia de ejecución sin haber cerrado lo que ha abierto.

     

    Hola juan carlos, es correcta la respuesta, pero como consejo a seguir, para próximos proyectos, inclusive para este, pero no considero que sea la respuesta por eso la desmarque, y la votare como util, asi cuando la encuentre, la solucion la pondre para que pueda ser marcada.

     

    muchas gracias 

     

    Un saludo

    Tuesday, May 04, 2010 8:22 AM
  • Muy extraño, pero creo que la solución sigue siendo esa,

    segun analizo, la primera descarga falla, luego en el catch haces un reintento pero ahí te falla porque dice que el archivo ya esta siendo usado... y claro que esta siendo usado porque como la descarga fallo la primera vez al procesar la excepción no estas liberando bien los recursos, es más en ese finally te salta la excepción de nuevo al no poder hacer Close de un stream dado que su stream base ya fue cerrado.

    mira modifica el orden de este segmento:

     

     finally
     {
      // Close streams
      stream.Close();
      reader.Close();
      writer.Close();
    
     }

     

     dejalo así, cierras primero los streams dependientes y al final los no dependientes, también validas cuales objetos han sido inicializados, y finalmente cambias el scope de las declaraciones para facilitar atrapar la excepión en cascada cuando se requiera.

     

     public FtpStatusCode Download(string destinationFile, Uri downloadUri, string userName, string password)
     {
      Stream stream = null;
      StreamReader reader = null;
      StreamWriter writer = null;
    
      try
      {
      // Check if the URI is and FTP site
      if (downloadUri.Scheme != Uri.UriSchemeFtp)
      {
       throw new ArgumentException("Invalid FTP site");
      }
    
      // Set up the request
      FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(downloadUri);
      // Credentials for FTP URI
      ftpRequest.Credentials = new NetworkCredential(userName, password);
      // Set method as file download.
      ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
      // get the response object
      FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
      
      // get the file as a stream from the response object and write it as a file stream to the local disk
      try
      {
       stream = ftpResponse.GetResponseStream();
       reader = new StreamReader(stream, Encoding.UTF8);
       writer = new StreamWriter(destinationFile, false);
       writer.Write(reader.ReadToEnd());
       return ftpResponse.StatusCode;
      }
      finally
      {
       // Close streams
       if (writer != null)
       writer.Close();
       if (reader != null)
       reader.Close();
       if (stream != null)
       stream.Close();
      }
      }
      catch (Exception ex)
      {
    #if DEBUG
      MessageBox.Show("Eror:"+ ex.ToString());
    #endif
      throw ex;
      }
     }

     

    Si despues de esto sigues con los problemas te sugiero 3 cosas:

    1- utiliza el Process Monitor de windows internals

    2- hasle windbg

    3- pasanos la solución para revisarla

     

    saludos


    Juan Carlos Ruiz
    Microsoft MVP - Visual C#
    Visita mi blog:

    Ideas de Un Conejo - http://juank.black-byte.com

    Tuesday, May 04, 2010 2:45 PM
    Moderator
  • ¡Hola!

    ¿Las informaciones fueran útiles para solucionar su problema?

    ¡Gracias!
    Rafael Fagundes - Marque la respuesta como correcta si te ha sido de utilidad!
    Monday, May 10, 2010 1:04 PM
    Moderator
  • buenas tardes, estoy con las pruebas y en breve os diré que tal esta funcionando, de momento parece que en todo el fin de semana no se volvio a bloquear el archivo, luego mas tarde si todo va bien digo como fue.

     

    muchas gracias

    un saludo

    Monday, May 10, 2010 2:37 PM
  • eh concluido la prueba y al parecer ya no sucede lo que me venia pasando , marque como respuesta  la de Juan Carlos, ya que esa es la solucion que implemente y funciona.

     

    un saludo a todos y muchas gracias por su ayuda

    Monday, May 10, 2010 5:22 PM