Cargar archivo a FTP usando C #

112

Intento subir un archivo a un servidor FTP con C #. El archivo se carga pero con cero bytes.

private void button2_Click(object sender, EventArgs e)
{
    var dirPath = @"C:/Documents and Settings/sander.GD/Bureaublad/test/";

    ftp ftpClient = new ftp("ftp://example.com/", "username", "password");

    string[] files = Directory.GetFiles(dirPath,"*.*");

    var uploadPath = "/httpdocs/album";

    foreach (string file in files)
    {
        ftpClient.createDirectory("/test");

        ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
    }

    if (string.IsNullOrEmpty(txtnaam.Text))
    {
        MessageBox.Show("Gelieve uw naam in te geven !");
    }
}
webvision
fuente
18
¿Por qué casi 2 años después siguen funcionando las credenciales FTP originales?
FreeAsInBeer
1
posible duplicado del archivo de carga en ftp
Frédéric
¿Podría probar lo que se menciona en la pregunta a la que @Frederic se vinculó y volver ... más aún no está claro qué api está usando para cargar ftp ...?
deostroll

Respuestas:

272

Las respuestas existentes son válidas, pero ¿por qué reinventar la rueda y molestarse con WebRequesttipos de nivel inferior mientras WebClientya implementa la carga FTP de manera ordenada?

using (var client = new WebClient())
{
    client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
    client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}
Saeb Amini
fuente
39
Solo un centavo: puede reemplazar la cadena mágica "STOR" por WebRequestMethods.Ftp.UploadFile
Haga clic en Aceptar
Desafortunadamente, no parece haber una forma de usar WebClient para crear un nuevo directorio para cargar un archivo.
danludwig
1
PSA: webrequest ya no se recomienda, estas son ahora las alternativas oficiales
Pacharrin
Hola, ¿qué indica path.zip en el método UploadFile? ¿Necesito un nombre de archivo para incluir después del nombre de host? Solo tengo un archivo txt para enviar, pensé que el nombre del archivo y la ruta a ese archivo se mencionan en localFile.
Skanda
43
public void UploadFtpFile(string folderName, string fileName)
{

    FtpWebRequest request;

    string folderName; 
    string fileName;
    string absoluteFileName = Path.GetFileName(fileName);

    request = WebRequest.Create(new Uri(string.Format(@"ftp://{0}/{1}/{2}", "127.0.0.1", folderName, absoluteFileName))) as FtpWebRequest;
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.UseBinary = 1;
    request.UsePassive = 1;
    request.KeepAlive = 1;
    request.Credentials =  new NetworkCredential(user, pass);
    request.ConnectionGroupName = "group"; 

    using (FileStream fs = File.OpenRead(fileName))
    {
        byte[] buffer = new byte[fs.Length];
        fs.Read(buffer, 0, buffer.Length);
        fs.Close();
        Stream requestStream = request.GetRequestStream();
        requestStream.Write(buffer, 0, buffer.Length);
        requestStream.Flush();
        requestStream.Close();
    }
}

Cómo utilizar

UploadFtpFile("testFolder", "E:\\filesToUpload\\test.img");

usa esto en tu foreach

y solo necesitas crear una carpeta una vez

para crear una carpeta

request = WebRequest.Create(new Uri(string.Format(@"ftp://{0}/{1}/", "127.0.0.1", "testFolder"))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)request.GetResponse();
cdev
fuente
3
La respuesta pierde una llamada a request.GetResponse(). Sin él, la carga no funcionará (legítimamente) en algunos servidores. Consulte Cómo: cargar archivos con FTP .
Martin Prikryl
Estoy tentado a -1 por tragarme silenciosamente las excepciones. ¿Puedes eliminar ese dañino try-catch-block?
Heinzi
33

La manera más fácil

La forma más trivial de subir un archivo a un servidor FTP usando .NET framework es usando el WebClient.UploadFilemétodo :

WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UploadFile("ftp://ftp.example.com/remote/path/file.zip", @"C:\local\path\file.zip");

Opciones avanzadas

Si necesita un mayor control, que WebClientno ofrece (como cifrado TLS / SSL , modo ASCII, modo activo, etc.), utilice FtpWebRequest. Una forma fácil es simplemente copiar FileStreama en una transmisión FTP usando Stream.CopyTo:

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;  

using (Stream fileStream = File.OpenRead(@"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
    fileStream.CopyTo(ftpStream);
}

Seguimiento del progreso

Si necesita monitorear el progreso de una carga, debe copiar el contenido por partes usted mismo:

FtpWebRequest request =
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;  

using (Stream fileStream = File.OpenRead(@"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
    byte[] buffer = new byte[10240];
    int read;
    while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        ftpStream.Write(buffer, 0, read);
        Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
    } 
}

Para el progreso de la GUI (WinForms ProgressBar), vea el ejemplo de C # en:
¿Cómo podemos mostrar la barra de progreso para cargar con FtpWebRequest?


Subiendo carpeta

Si desea cargar todos los archivos de una carpeta, consulte
Cargar directorio de archivos al servidor FTP mediante WebClient .

Para una carga recursiva, consulte
Carga recursiva al servidor FTP en C #

Martin Prikryl
fuente
10

Lo siguiente funciona para mí:

public virtual void Send(string fileName, byte[] file)
{
    ByteArrayToFile(fileName, file);

    var request = (FtpWebRequest) WebRequest.Create(new Uri(ServerUrl + fileName));

    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.UsePassive = false;
    request.Credentials = new NetworkCredential(UserName, Password);
    request.ContentLength = file.Length;

    var requestStream = request.GetRequestStream();
    requestStream.Write(file, 0, file.Length);
    requestStream.Close();

    var response = (FtpWebResponse) request.GetResponse();

    if (response != null)
        response.Close();
}

No puede leer enviar el parámetro de archivo en su código, ya que es solo el nombre del archivo.

Utilice lo siguiente:

byte[] bytes = File.ReadAllBytes(dir + file);

Para obtener el archivo para que pueda pasarlo al Sendmétodo.

Björn Mårtensson
fuente
hola, tengo una carpeta con archivos ... ¿cómo puedo subirla a un servidor FTP? Este código no sé exactamente cómo funciona esto?
webvision
en el bucle foreach, llame a este método con la entrada adecuada.
nRk
8
public static void UploadFileToFtp(string url, string filePath, string username, string password)
{
    var fileName = Path.GetFileName(filePath);
    var request = (FtpWebRequest)WebRequest.Create(url + fileName);

    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.Credentials = new NetworkCredential(username, password);
    request.UsePassive = true;
    request.UseBinary = true;
    request.KeepAlive = false;

    using (var fileStream = File.OpenRead(filePath))
    {
        using (var requestStream = request.GetRequestStream())
        {
            fileStream.CopyTo(requestStream);
            requestStream.Close();
        }
    }

    var response = (FtpWebResponse)request.GetResponse();
    Console.WriteLine("Upload done: {0}", response.StatusDescription);
    response.Close();
}
Christian Moser
fuente
¿Por qué establece KeepAlive = false? ¿Está seguro de que es necesario requestStream.Close ()? Usas requestStream dentro del uso, así que creo que cerrará la transmisión por sí solo.
Kate
2

En el primer ejemplo debe cambiarlos a:

requestStream.Flush();
requestStream.Close();

Primero enjuague y luego cierre.

marik
fuente
1

Esto funciona para mí, este método enviará un archivo SFTP a una ubicación dentro de su red. Utiliza la biblioteca SSH.NET.2013.4.7. Uno puede descargarla gratis.

    //Secure FTP
    public void SecureFTPUploadFile(string destinationHost,int port,string username,string password,string source,string destination)

    {
        ConnectionInfo ConnNfo = new ConnectionInfo(destinationHost, port, username, new PasswordAuthenticationMethod(username, password));

        var temp = destination.Split('/');
        string destinationFileName = temp[temp.Count() - 1];
        string parentDirectory = destination.Remove(destination.Length - (destinationFileName.Length + 1), destinationFileName.Length + 1);


        using (var sshclient = new SshClient(ConnNfo))
        {
            sshclient.Connect();
            using (var cmd = sshclient.CreateCommand("mkdir -p " + parentDirectory + " && chmod +rw " + parentDirectory))
            {
                cmd.Execute();
            }
            sshclient.Disconnect();
        }


        using (var sftp = new SftpClient(ConnNfo))
        {
            sftp.Connect();
            sftp.ChangeDirectory(parentDirectory);
            using (var uplfileStream = System.IO.File.OpenRead(source))
            {
                sftp.UploadFile(uplfileStream, destinationFileName, true);
            }
            sftp.Disconnect();
        }
    }
C.Poh
fuente
Esta respuesta parece ser la única solución para mi sftp. Esperando probarlo.
Olorunfemi Ajibulu
1

fecha de publicación: 26/06/2018

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp

using System;
using System.IO;
using System.Net;
using System.Text;

namespace Examples.System.Net
{
    public class WebRequestGetExample
    {
    public static void Main ()
    {
        // Get the object used to communicate with the server.
        FtpWebRequest request = 
(FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
        request.Method = WebRequestMethods.Ftp.UploadFile;

        // This example assumes the FTP site uses anonymous logon.
        request.Credentials = new NetworkCredential("anonymous", 
"[email protected]");

        // Copy the contents of the file to the request stream.
        byte[] fileContents;
        using (StreamReader sourceStream = new StreamReader("testfile.txt"))
        {
            fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
        }

        request.ContentLength = fileContents.Length;

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(fileContents, 0, fileContents.Length);
        }

        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        {
            Console.WriteLine($"Upload File Complete, status 
{response.StatusDescription}");
        }
    }
}
}
Uzay
fuente
0

He observado que

  1. Falta FtpwebRequest.
  2. Como el destino es FTP, se requiere NetworkCredential.

He preparado un método que funciona así, puedes reemplazar el valor de la variable ftpurl con el parámetro TargetDestinationPath. Probé este método en la aplicación winforms:

private void UploadProfileImage(string TargetFileName, string TargetDestinationPath, string FiletoUpload)
        {
            //Get the Image Destination path
            string imageName = TargetFileName; //you can comment this
            string imgPath = TargetDestinationPath; 

            string ftpurl = "ftp://downloads.abc.com/downloads.abc.com/MobileApps/SystemImages/ProfileImages/" + imgPath;
            string ftpusername = krayknot_DAL.clsGlobal.FTPUsername;
            string ftppassword = krayknot_DAL.clsGlobal.FTPPassword;
            string fileurl = FiletoUpload;

            FtpWebRequest ftpClient = (FtpWebRequest)FtpWebRequest.Create(ftpurl);
            ftpClient.Credentials = new System.Net.NetworkCredential(ftpusername, ftppassword);
            ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
            ftpClient.UseBinary = true;
            ftpClient.KeepAlive = true;
            System.IO.FileInfo fi = new System.IO.FileInfo(fileurl);
            ftpClient.ContentLength = fi.Length;
            byte[] buffer = new byte[4097];
            int bytes = 0;
            int total_bytes = (int)fi.Length;
            System.IO.FileStream fs = fi.OpenRead();
            System.IO.Stream rs = ftpClient.GetRequestStream();
            while (total_bytes > 0)
            {
                bytes = fs.Read(buffer, 0, buffer.Length);
                rs.Write(buffer, 0, bytes);
                total_bytes = total_bytes - bytes;
            }
            //fs.Flush();
            fs.Close();
            rs.Close();
            FtpWebResponse uploadResponse = (FtpWebResponse)ftpClient.GetResponse();
            string value = uploadResponse.StatusDescription;
            uploadResponse.Close();
        }

Avísame en caso de cualquier problema, o aquí hay un enlace más que puede ayudarte:

https://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx

Kshitij Jhangra
fuente