2

I am trying to download a file from one FTP server, and then upload it to a different FTP. I only figured out how to upload local files and download XML via FTP so far.

Here is my method to upload local file to FTP:

    private void UploadLocalFile(string sourceFileLocation, string targetFileName)
    {
        try
        {
            string ftpServerIP = "ftp://testing.com/ContentManagementSystem/"+ Company +"/Prod";
            string ftpUserID = Username;
            string ftpPassword = Password;
            string filename = "ftp://" + ftpServerIP + "/" + targetFileName;
            FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename);
            ftpReq.UseBinary = true;
            ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
            ftpReq.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
            ftpReq.Proxy = null;

            byte[] b = File.ReadAllBytes(sourceFileLocation);

            ftpReq.ContentLength = b.Length;
            using (Stream s = ftpReq.GetRequestStream())
            {
                s.Write(b, 0, b.Length);
            }
        }
        catch (WebException ex)
        {
            String status = ((FtpWebResponse)ex.Response).StatusDescription;
            Console.WriteLine(status);
        }
    }

And here is my method for downloading XML from FTP:

    private static XmlDocument DownloadFtpXml(string uri, int retryLimit)
    {
        var returnDocument = new XmlDocument();
        try
        {
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.Credentials = new NetworkCredential(Username, Password);
            request.UsePassive = true;
            request.Proxy = new WebProxy();

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

            using (Stream responseStream = response.GetResponseStream())
            {
                returnDocument.Load(responseStream);
            }
        }
        catch (WebException ex)
        {
            if (ex.Response != null)
            {
                FtpWebResponse response = (FtpWebResponse)ex.Response;
                if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                {
                }
            }
        }
        return returnDocument;
    }

I'm unsure exactly how to do it, but I'm trying to create a method that will download something (content will be a video or image) from one FTP and then turn around and upload what I've just downloaded (that I'll have held in memory) to a different FTP.

Please help!

adarom1987
  • 41
  • 1
  • 4
  • 1
    are you able to use SFTP instead? are third party tools allowed? http://stackoverflow.com/questions/6415562/ssh-file-transfer-protocol-sftp-using-c-sharp – jdu Jul 14 '15 at 20:07
  • Save the Xml document in a temporary local file then upload that. Looks like you have all the code there, just need to add that one extra step. Although you say the content will be a video or image, why are you saving it in an Xml document (will throw exceptions if you try to `.Load` something that isn't Xml)? – Ron Beyer Jul 14 '15 at 20:09
  • Instead of a temp file, you may directly copy from input stream (got from download) to output stream (used to write in upload process). – Graffito Jul 14 '15 at 20:19
  • okay excellent. I'll try some combination of these options above and report back. we're not setup to use SFTP yet, or I would have gone that route. third party tools are acceptable, but I'll try the temp local route and see where that takes me! – adarom1987 Jul 14 '15 at 20:22

1 Answers1

2

You were so close! Use a stream to convert your download into a byte array for upload.

I recently made a program to do just this! This will currently copy all files from one FTP directory to another so long as there is not a file in the target directory with the same name. It would be easy to change if you only wanted to copy one file, just use the copyFile, toByteArray and upload functions:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace Copy_From_FTP
{
    class Program
    {

        public static void Main(string[] args)
        {
            List<FileName> sourceFileList = new List<FileName>();
            List<FileName> targetFileList = new List<FileName>();

            //string targetURI = ftp://www.target.com
            //string targetUser = userName
            //string targetPass = passWord
            //string sourceURI = ftp://www.source.com
            //string sourceUser = userName
            //string sourcePass = passWord

            getFileLists(sourceURI, sourceUser, sourcePass, sourceFileList, targetURI, targetUser, targetPass, targetFileList);

            Console.WriteLine(sourceFileList.Count + " files found!");

            CheckLists(sourceFileList, targetFileList);
            targetFileList.Sort();

            Console.WriteLine(sourceFileList.Count + " unique files on sourceURI"+Environment.NewLine+"Attempting to move them.");

            foreach(var file in sourceFileList)
            {
                try
                {
                    CopyFile(file.fName, sourceURI, sourceUser, sourcePass, targetURI, targetUser, targetPass);
                }
                catch
                {
                    Console.WriteLine("There was move error with : "+file.fName);
                }                    
            }            
        }

        public class FileName : IComparable<FileName>
        {
            public string fName { get; set; }
            public int CompareTo(FileName other)
            {
                return fName.CompareTo(other.fName);
            }
        }

        public static void CheckLists(List<FileName> sourceFileList, List<FileName> targetFileList)
        {
            for (int i = 0; i < sourceFileList.Count;i++ )
            {
                if (targetFileList.BinarySearch(sourceFileList[i]) > 0)
                {
                    sourceFileList.RemoveAt(i);
                    i--;
                }
            }
        }

        public static void getFileLists(string sourceURI, string sourceUser, string sourcePass, List<FileName> sourceFileList,string targetURI, string targetUser, string targetPass, List<FileName> targetFileList)
        {
            string line = "";
            /////////Source FileList
            FtpWebRequest sourceRequest;
            sourceRequest = (FtpWebRequest)WebRequest.Create(sourceURI);
            sourceRequest.Credentials = new NetworkCredential(sourceUser, sourcePass);
            sourceRequest.Method = WebRequestMethods.Ftp.ListDirectory;
            sourceRequest.UseBinary = true;
            sourceRequest.KeepAlive = false;
            sourceRequest.Timeout = -1;
            sourceRequest.UsePassive = true;
            FtpWebResponse sourceRespone = (FtpWebResponse)sourceRequest.GetResponse();
            //Creates a list(fileList) of the file names
            using (Stream responseStream = sourceRespone.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    line = reader.ReadLine();
                    while (line != null)
                    {
                        var fileName = new FileName
                        {
                            fName = line
                        };
                        sourceFileList.Add(fileName);
                        line = reader.ReadLine();
                    }
                }
            }
            /////////////Target FileList
            FtpWebRequest targetRequest;
            targetRequest = (FtpWebRequest)WebRequest.Create(targetURI);
            targetRequest.Credentials = new NetworkCredential(targetUser, targetPass);
            targetRequest.Method = WebRequestMethods.Ftp.ListDirectory;
            targetRequest.UseBinary = true;
            targetRequest.KeepAlive = false;
            targetRequest.Timeout = -1;
            targetRequest.UsePassive = true;
            FtpWebResponse targetResponse = (FtpWebResponse)targetRequest.GetResponse();
            //Creates a list(fileList) of the file names
            using (Stream responseStream = targetResponse.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(responseStream))
                {
                    line = reader.ReadLine();
                    while (line != null)
                    {
                        var fileName = new FileName
                        {
                            fName = line
                        };
                        targetFileList.Add(fileName);
                        line = reader.ReadLine();
                    }
                }
            }
        }

        public static void CopyFile(string fileName, string sourceURI, string sourceUser, string sourcePass,string targetURI, string targetUser, string targetPass )
        {
            try
            {
                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(sourceURI + fileName);
                request.Method = WebRequestMethods.Ftp.DownloadFile;
                request.Credentials = new NetworkCredential(sourceUser, sourcePass);
                FtpWebResponse response = (FtpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                Upload(fileName, ToByteArray(responseStream),targetURI,targetUser, targetPass);
                responseStream.Close();
            }
            catch
            {
                Console.WriteLine("There was an error with :" + fileName);
            }
        }

        public static Byte[] ToByteArray(Stream stream)
        {
            MemoryStream ms = new MemoryStream();
            byte[] chunk = new byte[4096];
            int bytesRead;
            while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
            {
                ms.Write(chunk, 0, bytesRead);
            }

            return ms.ToArray();
        }

        public static bool Upload(string FileName, byte[] Image, string targetURI,string targetUser, string targetPass)
        {
            try
            {
                FtpWebRequest clsRequest = (FtpWebRequest)WebRequest.Create(targetURI+FileName);
                clsRequest.Credentials = new NetworkCredential(targetUser, targetPass);
                clsRequest.Method = WebRequestMethods.Ftp.UploadFile;
                Stream clsStream = clsRequest.GetRequestStream();
                clsStream.Write(Image, 0, Image.Length);
                clsStream.Close();
                clsStream.Dispose();
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}

You may run into issues if you are using things that have special encoding, like text documents. That can be changed by the way the upload function is used. If you're doing text files, use:

 System.Text.Encoding.UTF8.GetBytes(responseStream)

instead of

ToByteArray(responseStream)

You could do a simple extension check of your file before executing the upload.

John Boling
  • 464
  • 6
  • 14