Carica file su FTP usando C #


112

Provo a caricare un file su un server FTP con C #. Il file viene caricato ma con zero byte.

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 !");
    }
}

18
Perché quasi 2 anni dopo le credenziali FTP originali funzionano ancora?
FreeAsInBeer

1
possibile duplicato del file
Frédéric

Potresti provare quanto menzionato nella domanda collegata a @Frederic e tornare indietro ... inoltre non è chiaro quale api stai usando per l'upload ftp ...
deostroll

Risposte:


272

Le risposte esistenti sono valide, ma perché reinventare la ruota e preoccuparsi di WebRequesttipi di livello inferiore mentre WebClientimplementa già il caricamento FTP in modo ordinato:

using (var client = new WebClient())
{
    client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
    client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}

39
Solo un centesimo: puoi sostituire la stringa magica "STOR" per WebRequestMethods.Ftp.UploadFile
Fare clic su Ok

Sfortunatamente, non sembra esserci un modo per utilizzare WebClient per creare una nuova directory in cui caricare un file.
Danludwig

1
PSA: webrequest non è più consigliato, ora queste sono le alternative ufficiali
Pacharrin

Ciao, cosa indica path.zip nel metodo UploadFile? Ho bisogno di un nome file da includere dopo il nome host? Ho solo un file txt da inviare, ho pensato che il nome del file e il percorso di quel file fossero menzionati in 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();
    }
}

Come usare

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

usalo nel tuo foreach

e devi solo creare la cartella una volta

per creare una cartella

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

3
La risposta manca una chiamata a request.GetResponse(). Senza di esso, il caricamento non funzionerà (giustamente) su alcuni server. Vedere Procedura: caricare file con FTP .
Martin Prikryl

Sono tentato di -1 per inghiottire silenziosamente le eccezioni. Puoi rimuovere quel dannoso blocco try-catch?
Heinzi

33

Il modo più semplice

Il modo più semplice per caricare un file su un server FTP utilizzando .NET framework è utilizzare il WebClient.UploadFilemetodo :

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");

Opzioni avanzate

Se hai bisogno di un controllo maggiore, che WebClientnon offre (come crittografia TLS / SSL , modalità ASCII, modalità attiva, ecc.), Usa FtpWebRequest. Il modo semplice è copiare semplicemente un FileStreamin un flusso FTP utilizzando 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);
}

Monitoraggio dei progressi

Se è necessario monitorare l'avanzamento di un caricamento, è necessario copiare i contenuti in blocchi da soli:

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

Per lo stato di avanzamento della GUI (WinForms ProgressBar), vedere l'esempio C # su:
Come possiamo mostrare la barra di avanzamento per il caricamento con FtpWebRequest


Caricamento cartella

Se si desidera caricare tutti i file da una cartella, vedere
Caricamento della directory dei file sul server FTP utilizzando WebClient .

Per un caricamento ricorsivo, vedere
Caricamento ricorsivo sul server FTP in C #


10

Il seguente funziona per me:

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

Non puoi leggere invia il parametro del file nel tuo codice poiché è solo il nome del file.

Utilizza il seguente:

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

Per ottenere il file in modo da poterlo passare al Sendmetodo.


ciao, ho una cartella con dei file al suo interno .. come posso semplicemente caricarla su un server FTP? Questo codice non so esattamente come funziona?
webvision

nel ciclo foreach chiama questo metodo con l'input appropriato.
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();
}

perché imposti KeepAlive = false? Sei sicuro che sia necessario requestStream.Close ()? Usi requestStream all'interno, quindi penso che chiuderà lo stream da solo.
Kate

2

Nel primo esempio bisogna cambiarli in:

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

Prima vampata e dopo quella chiusura.


1

Questo funziona per me, questo metodo eseguirà l'SFTP di un file in una posizione all'interno della rete. Utilizza la libreria SSH.NET.2013.4.7, che puoi scaricare 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();
        }
    }

Questa risposta sembra l'unica soluzione per il mio sftp. In attesa di provarlo.
Olorunfemi Ajibulu

1

data di pubblicazione: 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", 
"janeDoe@contoso.com");

        // 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}");
        }
    }
}
}

0

Ho osservato che -

  1. FtpwebRequest è mancante.
  2. Poiché il target è FTP, è necessario NetworkCredential.

Ho preparato un metodo che funziona così, puoi sostituire il valore della variabile ftpurl con il parametro TargetDestinationPath. Avevo testato questo metodo sull'applicazione 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();
        }

Fammi sapere in caso di problemi, o ecco un altro link che può aiutarti:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.