Saltar al contenido

Cómo verificar si el archivo existe en FTP antes de FtpWebRequest

Solución:

var request = (FtpWebRequest)WebRequest.Create
    ("ftp://ftp.domain.com/doesntexist.txt");
request.Credentials = new NetworkCredential("user", "pass");
request.Method = WebRequestMethods.Ftp.GetFileSize;

try
{
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (WebException ex)
{
    FtpWebResponse response = (FtpWebResponse)ex.Response;
    if (response.StatusCode ==
        FtpStatusCode.ActionNotTakenFileUnavailable)
    {
        //Does not exist
    }
}

Como regla general, es una mala idea usar Excepciones para la funcionalidad en su código de esta manera, sin embargo, en este caso, creo que es una victoria para el pragmatismo. La lista de llamadas en el directorio tiene el potencial de ser MUCHO más ineficiente que usar excepciones de esta manera.

Si no es así, ¡tenga en cuenta que no es una buena práctica!

EDITAR: “¡Funciona para mí!”

Esto parece funcionar en la mayoría de los servidores ftp, pero no en todos. Algunos servidores requieren enviar “TYPE I” antes de que funcione el comando SIZE. Uno habría pensado que el problema debería resolverse de la siguiente manera:

request.UseBinary = true;

Desafortunadamente, es una limitación por diseño (¡gran error!) Que a menos que FtpWebRequest esté descargando o cargando un archivo, NO enviará “TIPO I”. Vea la discusión y la respuesta de Microsoft aquí.

En su lugar, recomendaría usar el siguiente WebRequestMethod, esto me funciona en todos los servidores que probé, incluso en los que no devuelven un tamaño de archivo.

WebRequestMethods.Ftp.GetDateTimestamp

Porque

request.Method = WebRequestMethods.Ftp.GetFileSize

puede fallar en algún caso (550: TAMAÑO no permitido en el modo ASCII), en su lugar, puede verificar la marca de tiempo.

reqFTP.Credentials = new NetworkCredential(inf.LogOn, inf.Password);
reqFTP.UseBinary = true;
reqFTP.Method = WebRequestMethods.Ftp.GetDateTimestamp;

FtpWebRequest (ni ninguna otra clase en .NET) no tiene ningún método explícito para verificar la existencia de un archivo en el servidor FTP. Necesitas abusar de una solicitud como GetFileSize o GetDateTimestamp.

string url = "ftp://ftp.example.com/remote/path/file.txt";

WebRequest request = WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.GetFileSize;
try
{
    request.GetResponse();
    Console.WriteLine("Exists");
}
catch (WebException e)
{
    FtpWebResponse response = (FtpWebResponse)e.Response;
    if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
    {
        Console.WriteLine("Does not exist");
    }
    else
    {
        Console.WriteLine("Error: " + e.Message);
    }
}

Si desea un código más sencillo, use alguna biblioteca FTP de terceros.

Por ejemplo, con el ensamblaje de WinSCP .NET, puede usar su Session.FileExists método:

SessionOptions sessionOptions = new SessionOptions {
    Protocol = Protocol.Ftp,
    HostName = "ftp.example.com",
    UserName = "username",
    Password = "password",
};

Session session = new Session();
session.Open(sessionOptions);

if (session.FileExists("/remote/path/file.txt"))
{
    Console.WriteLine("Exists");
}
else
{
    Console.WriteLine("Does not exist");
}

(Soy el autor de WinSCP)

¡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 *