Carregar arquivo para FTP usando C #

112

Tento fazer upload de um arquivo para um servidor FTP com C #. O arquivo é carregado, mas com zero 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
fonte
18
Por que quase 2 anos depois as credenciais de FTP originais ainda funcionam?
FreeAsInBeer
1
possível duplicata do arquivo
Frédéric
Você poderia tentar o que é mencionado na pergunta @Frederic vinculada a e voltar ... ou seja, não está claro qual api você está usando para upload por ftp ...
deostroll

Respostas:

272

As respostas existentes são válidas, mas por que reinventar a roda e se preocupar com WebRequesttipos de nível inferior enquanto WebClientjá implementa o upload de FTP de forma organizada:

using (var client = new WebClient())
{
    client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
    client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}
Saeb Amini
fonte
39
Apenas um centavo: você pode substituir a string mágica "STOR" por WebRequestMethods.Ftp.UploadFile
Clique em Ok
Infelizmente, não parece haver uma maneira de usar o WebClient para criar um novo diretório para carregar um arquivo.
danludwig
1
PSA: webrequest não é mais recomendado, agora são as alternativas oficiais
Pacharrin
Olá, o que o path.zip no método UploadFile indica? Eu preciso incluir um nome de arquivo após o nome do host? Eu só tenho um arquivo txt para enviar, pensei que o nome do arquivo e o caminho para esse arquivo são mencionados em localFile.
Skanda
42
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();
    }
}

Como usar

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

use isso em seu foreach

e você só precisa criar a pasta uma vez

para criar uma pasta

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
fonte
3
A resposta perde uma chamada para request.GetResponse(). Sem ele, o upload não funcionará (com razão) em alguns servidores. Consulte Como: Carregar arquivos com FTP .
Martin Prikryl de
Estou tentado a -1 por engolir exceções silenciosamente. Você pode remover esse bloco try-catch prejudicial?
Heinzi
32

Caminho mais fácil

A maneira mais comum de fazer upload de um arquivo para um servidor FTP usando o .NET framework é usando o 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");

Opções avançadas

Se precisar de um controle maior, que WebClientnão oferece (como criptografia TLS / SSL , modo ASCII, modo ativo, etc), use FtpWebRequest. A maneira fácil é apenas copiar um FileStreampara um fluxo de 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);
}

Monitoramento de progresso

Se você precisar monitorar o progresso de um upload, deverá copiar o conteúdo por partes você mesmo:

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 o progresso da GUI (WinForms ProgressBar), consulte o exemplo C # em:
Como podemos mostrar a barra de progresso para upload com FtpWebRequest


Carregando pasta

Se você deseja carregar todos os arquivos de uma pasta, consulte
Carregar diretório de arquivos para o servidor FTP usando WebClient .

Para um upload recursivo, consulte
Upload recursivo para o servidor FTP em C #

Martin Prikryl
fonte
10

O seguinte funciona para mim:

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();
}

Você não pode ler o parâmetro de envio do arquivo em seu código, pois é apenas o nome do arquivo.

Use o seguinte:

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

Para obter o arquivo para que você possa passá-lo para o Sendmétodo.

Björn Mårtensson
fonte
Olá, tenho uma pasta com arquivos. Como posso apenas fazer upload para um servidor FTP? Esse código não sei exatamente como isso funciona?
webvision
no loop foreach, chame esse método com a entrada apropriada.
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
fonte
por que você define KeepAlive = false? Tem certeza de que é necessário requestStream.Close ()? Você usa o requestStream dentro do using então eu acho que ele vai fechar o stream sozinho.
Kate
2

No primeiro exemplo, deve ser alterado para:

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

Primeiro enxágue e depois feche.

marik
fonte
1

Isso funciona para mim, esse método fará o SFTP de um arquivo para um local na sua rede. Ele usa a biblioteca SSH.NET.2013.4.7. Basta fazer o download gratuitamente.

    //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
fonte
Esta resposta parece ser a única solução para o meu sftp. Esperando para testar.
Olorunfemi Ajibulu
1

data de publicação: 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
fonte
0

Eu observei que -

  1. FtpwebRequest está faltando.
  2. Como o destino é FTP, é necessário o NetworkCredential.

Eu preparei um método que funciona assim, você pode substituir o valor da variável ftpurl pelo parâmetro TargetDestinationPath. Eu testei este método no aplicativo 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();
        }

Avise-me caso haja algum problema ou aqui está mais um link que pode ajudá-lo:

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

Kshitij Jhangra
fonte