How to copy a file on an FTP server?

How do you copy a file on an FTP server? My goal is to copy ftp://www.mysite.com/test.jpg to ftp://www.mysite.com/testcopy.jpg. To rename a file, I would use:

var request = (FtpWebRequest)WebRequest.Create("ftp://www.mysite.com/test.jpg");
request.Credentials = new NetworkCredential(user, pass);
request.Method = WebRequestMethods.Ftp.Rename;
request.RenameTo = "testrename.jpg"
request.GetResponse().Close();

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

However, there is no Method for copying files. How would you do copy a file?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Try this:

static void Main(string[] args)
{
    CopyFile("countrylist.csv", "MySample.csv", "username", "password#");
}

public static bool CopyFile(string fileName, string FileToCopy, string userName, string password)
{
    try
    {
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.mysite.net/" + fileName);
        request.Method = WebRequestMethods.Ftp.DownloadFile;

        request.Credentials = new NetworkCredential(userName, password);
        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        Stream responseStream = response.GetResponseStream();
        Upload("ftp://ftp.mysite.net/" + FileToCopy, ToByteArray(responseStream), userName, password);
        responseStream.Close();
        return true;
    }
    catch
    {
        return false;
    }
}

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 FtpUsername, string FtpPassword)
{
    try
    {
        System.Net.FtpWebRequest clsRequest = (System.Net.FtpWebRequest)System.Net.WebRequest.Create(FileName);
        clsRequest.Credentials = new System.Net.NetworkCredential(FtpUsername, FtpPassword);
        clsRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
        System.IO.Stream clsStream = clsRequest.GetRequestStream();
        clsStream.Write(Image, 0, Image.Length);

        clsStream.Close();
        clsStream.Dispose();
        return true;
    }
    catch
    {
        return false;
    }
}

This downloads the file to a stream, and then uploads it.

Method 2

FtpWebRequest is a lightweight class. Microsoft felt it should be used by simple client to download and delete the files once the client is finish.

Method 3

I guess you can’t really do this with FTP. What you can do is download the file you want to copy and then upload it with a new name. For example:

        try
        {
            WebClient request = new WebClient();
            request.Credentials = new NetworkCredential(user, pass);
            byte[] data = request.DownloadData(host);
            MemoryStream file = new MemoryStream(data);
            Upload(data);
        }
        catch (Exception ex)
        {

        }

    ...

    private void Upload(byte[] buffer)
    {
        try
        {
            FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(newname);

            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.Credentials = new NetworkCredential(user, pass);

            Stream reqStream = request.GetRequestStream();
            reqStream.Write(buffer, 0, buffer.Length);
            reqStream.Close();

            var resp = (FtpWebResponse)request.GetResponse();
        }
        catch (Exception ex)
        {

        }
    }

Method 4

In our project we did someting like this

// pass parameters according to your need, 
// the below code is done in a hard coded manner for clarity
public void Copy()  
{
    // from where you want to copy
    var downloadRequest = (FtpWebRequest)WebRequest.Create("ftp://www.mysite.com/test.jpg");
    downloadRequest.Credentials = new NetworkCredential("userName", "passWord");
    downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;

    var ftpWebResponse = (FtpWebResponse)downloadRequest.GetResponse();
    var downloadResponse = ftpWebResponse.GetResponseStream();

    int buffLength = 2048;
    byte[] byteBuffer = new byte[buffLength];

    // bytes read from download stream. 
    // from documentation: When overridden in a derived class, reads a sequence of bytes from the  
    // current stream and advances the position within the stream by the number of bytes read.
    int bytesRead = downloadResponse.Read(byteBuffer, 0, buffLength);

    // the place where you want the file to go
    var uploadRequest = (FtpWebRequest)WebRequest.Create("ftp://www.mysite.com/testCopy.jpg");
    uploadRequest.Credentials = new NetworkCredential("userName", "passWord");
    uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;

    var uploadStream = uploadRequest.GetRequestStream();

    if (bytesRead > 0)
    {
        while (bytesRead > 0)
        {
            uploadStream.Write(byteBuffer, 0, bytesRead);
            bytesRead = downloadResponse.Read(byteBuffer, 0, buffLength);
        }
    }

    uploadStream.Close();
    uploadStream.Dispose();

    downloadResponse.Close();
    ftpWebResponse.Close();
    ((IDisposable)ftpWebResponse).Dispose();
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x