【问题标题】:Upload file to FTP using C#使用 C# 将文件上传到 FTP
【发布时间】:2013-02-22 12:11:24
【问题描述】:

我尝试使用 C# 将文件上传到 FTP 服务器。文件已上传,但字节数为零。

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

【问题讨论】:

标签: c# .net file-upload ftp


【解决方案1】:

现有的答案是有效的,但是为什么要重新发明轮子并为较低级别的 WebRequest 类型而烦恼,而 WebClient 已经巧妙地实现了 FTP 上传:

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

【讨论】:

【解决方案2】:

最简单的方法

使用 .NET 框架将文件上传到 FTP 服务器最简单的方法是使用WebClient.UploadFile method

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

高级选项

如果您需要WebClient 不提供的更大控制(如TLS/SSL encryption、ascii/文本传输模式、活动模式、传输恢复、进度监控等),请使用FtpWebRequest。简单的方法是使用Stream.CopyToFileStream 复制到FTP 流:

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

进度监控

如果你需要监控一个上传进度,你必须自己分块复制内容:

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

有关 GUI 进度 (WinForms ProgressBar),请参阅 C# 示例:
How can we show progress bar for upload with FtpWebRequest


上传文件夹

如果您想上传文件夹中的所有文件,请参阅
Upload directory of files to FTP server using WebClient

有关递归上传,请参阅
Recursive upload to FTP server in C#

【讨论】:

    【解决方案3】:

    .NET 5 Guide

    async Task<FtpStatusCode> FtpFileUploadAsync(string ftpUrl, string userName, string password, string filePath)
    {
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
        request.Method = WebRequestMethods.Ftp.UploadFile;
        request.Credentials = new NetworkCredential(userName, password);
    
        using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        using (Stream requestStream = request.GetRequestStream())
        {
            await fileStream.CopyToAsync(requestStream);
        }
    
        using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
        {
            return response.StatusCode;
        }
    }
    

    .NET 框架

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

    如何使用

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

    在你的 foreach 中使用它

    你只需要创建一次文件夹

    创建文件夹

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

    【讨论】:

    • 答案错过了对request.GetResponse()的呼叫。没有它,上传将无法(正确地)在某些服务器上工作。见How to: Upload Files with FTP
    【解决方案4】:

    以下对我有用:

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

    您无法读取代码中的发送文件参数,因为它只是文件名。

    使用以下内容:

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

    获取文件以便将其传递给Send 方法。

    【讨论】:

    • 你好,我有一个文件夹,里面有文件.. 我怎样才能将它上传到 FTP 服务器?这段代码我不知道它到底是怎么工作的?
    • 在 foreach 循环中使用适当的输入调用此方法。
    【解决方案5】:
    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();
    }
    

    【讨论】:

    • 为什么设置 KeepAlive = false?你确定 requestStream.Close() 是必要的吗?你在里面使用 requestStream 所以我认为它会自己关闭流。
    【解决方案6】:

    在第一个示例中必须将这些更改为:

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

    第一次刷新,然后关闭。

    【讨论】:

      【解决方案7】:

      这对我有用,这种方法会将文件 SFTP 到您网络中的某个位置。 它使用SSH.NET.2013.4.7库。可以免费下载。

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

      【讨论】:

      • 这个答案似乎是我 sftp 的唯一解决方案。等待测试。
      【解决方案8】:

      发布日期:2018 年 6 月 26 日

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

      【讨论】:

        【解决方案9】:

        我观察到 -

        1. FtpwebRequest 丢失。
        2. 由于目标是 FTP,所以需要 NetworkCredential。

        我已经准备了一个像这样工作的方法,你可以用参数 TargetDestinationPath 替换变量 ftpurl 的值。我已经在 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();
                }
        

        如果有任何问题,请告诉我,或者这里还有一个可以帮助您的链接:

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

        【讨论】:

          【解决方案10】:

          我发现的最好方法是 FluentFtp 你可以在这里找到回购: https://github.com/robinrodricks/FluentFTP 以及此处的快速入门示例: https://github.com/robinrodricks/FluentFTP/wiki/Quick-Start-Example.

          实际上这里有几个人推荐的 WebRequest 类,微软不再推荐了,看看这个页面: https://docs.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=net-5.0

          // create an FTP client and specify the host, username and password
          // (delete the credentials to use the "anonymous" account)
          FtpClient client = new FtpClient("123.123.123.123", "david", "pass123");
          
          // connect to the server and automatically detect working FTP settings
          client.AutoConnect();
          
          // upload a file and retry 3 times before giving up
          client.RetryAttempts = 3;
          client.UploadFile(@"C:\MyVideo.mp4", "/htdocs/big.txt", 
              FtpRemoteExists.Overwrite, false, FtpVerify.Retry);
          
          // disconnect! good bye!
          client.Disconnect();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-05-11
            • 2014-05-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多