Search code examples
c#.netftpsftpftpwebrequest

Change from C# FtpWebRequest FTP code to SFTP


I would really need some help to change from FTP transfer to SFTP. I added some lines in the comment but I'm new to programming and I don't know for sure what I also need to add to fix this problem. The programme works fine but at the moment you transfer your data via FTP. I read some questions here but for now, I couldn't find the right tipp rewrite the program to SFTP.

public class FTP
{
    private System.ComponentModel.BackgroundWorker bw = null;
    private long filesSize = 0;
    private long uploadSize = 0;
    private const int bufferLength = 2048;

    public FTP()
    {

    }

    public FTP(System.ComponentModel.BackgroundWorker thread, long allFilesSize)
    {
        bw = thread;
        filesSize = allFilesSize;
    }

    public string ReadUserFile()
    {
        WebClient req = new WebClient();

        req.Credentials = new NetworkCredential("", "");

        try
        {
            byte[] newFileData = req.DownloadData(); 
            return System.Text.Encoding.Default.GetString(newFileData);
        }
        catch
        {
            return null;
        }
    }

    public void UploadFile(
        string ftpServer, string filePath, string username, string password)
    {
        //Create SFTP request
        //Sftp client = new Sftp();
        //client.Connect(hostname);
        //client.Login(username, password);


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

        //Load the file
        //

        //Load the file
        FileStream stream = File.OpenRead(filePath);

        //Upload to Sftp Server
        //client.PutFile();


        //Upload file
        Stream reqStream = request.GetRequestStream();

        byte[] buffer = new byte[bufferLength];
        int count = 0;
        int readBytes = 0;

        do
        {
            readBytes = stream.Read(buffer, 0, bufferLength);
            reqStream.Write(buffer, 0, readBytes);
            count += readBytes;
            if (bw != null)
                bw.ReportProgress(CalculateProgress());
        }
        while (readBytes != 0);

        //Disconnect
        //client.Disconnect();


        stream.Close();
        reqStream.Close();
    }

    private int CalculateProgress()
    {
        uploadSize += bufferLength;

        return (Int32)(uploadSize/(filesSize / 100));
    }

    public void DeleteFile(
        string ftpServer, string filePath, string username, string password)
    {
        //Create SFTP request 
        //Sftp client = new Sftp();
        //client.Connect(hostname);
        //client.Login(username, password);

        //Create FTP request
        FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create();
        request.Method = WebRequestMethods.Ftp.DeleteFile;
        request.Credentials = new NetworkCredential(username, password);
        request.UsePassive = true;
        request.UseBinary = true;
        request.KeepAlive = false;

        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        response.Close();
    }

    public string[] GetFileList(
        string ftpServer, string username, string password)
    {
        string[] fileList;
        StringBuilder result = new StringBuilder();
        FtpWebRequest request;

        try
        {
            request = (FtpWebRequest)FtpWebRequest.Create(new Uri());
            request.UseBinary = true;
            request.Credentials = new NetworkCredential(username, password);
            request.Method = WebRequestMethods.Ftp.ListDirectory;
            WebResponse response = request.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());

            string line = reader.ReadLine();

            while (line != null)
            {
                if (line.StartsWith("./"))
                    line = line.Substring(2, line.Length - 2);

                result.Append(line);
                result.Append("\n");
                line = reader.ReadLine();
            }

            result.Remove(result.ToString().LastIndexOf('\n'), 1);
            reader.Close();
            response.Close();

            return result.ToString().Split('\n');
        }
        catch
        {
            //Error
            fileList = null;
            return fileList;
        }
    }

Solution

  • There's no simple way to switch from FTP to SFTP in C#/.NET, if you are currently using .NET FtpWebRequest API.

    There's no support for SFTP in .NET framework. You need 3rd party library: SFTP Libraries for .NET.

    That also means that you basically need to scratch your current code and start from the very beginning. Not a single line in your current code would be useful for SFTP with any 3rd party library, as they have very different API to unusual FtpWebRequest.


    There are libraries that offer an uniform interface to both FTP and SFTP protocols.

    For example WinSCP .NET assembly supports FTP, FTPS, FTPES, SFTP and others (SCP, S3, WebDAV and WebDAVS) over the same interface.

    Though it is not a native .NET assembly. It's rather a thin wrapper over a console application.

    (I'm the author of WinSCP).