1

A while back I asked a question revolving around how to copy a file in chunks from one location to another: CopyFileEx "The parameter is invalid" error

I received the following code which was quite helpful.

    static void chunkCopyFile(string source, string destination, int bytesPerChunk)
    {
        uint bytesRead = 0;

        using (FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read)) {
            using (BinaryReader br = new BinaryReader(fs)) {
                using (FileStream fsDest = new FileStream(destination, FileMode.Create)) {
                    BinaryWriter bw = new BinaryWriter(fsDest);
                    byte[] buffer;

                    for (int i = 0; i < fs.Length; i += bytesPerChunk) {
                        buffer = br.ReadBytes(bytesPerChunk);
                        bw.Write(buffer);
                        bytesRead += Convert.ToUInt32(bytesPerChunk);
                        updateProgress(bytesRead);
                    }
                }
            }
        }
    }

However, I now need to convert this code to use FTP instead. I tried the obvious of just passing the FTP path to the filestream but it gave me an error saying "unsupported".

I already managed to get the file length, I'm just not sure how I can split the download into chunks. Any help is appreciated as always!

Code so far(not much)

static void chunkCopyFTPFile(string destination, int bytesPerChunk)
    {
        uint bytesRead = 0;

        fWR = (FtpWebRequest)WebRequest.Create("ftp://" + FTP_SERVER_NAME + "/test.txt");
        fWR.Method = WebRequestMethods.Ftp.DownloadFile;
        fWR.UseBinary = true;

        fWR.Credentials = new NetworkCredential(FTP_SERVER_USERNAME, FTP_SERVER_PASSWORD);

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

        Stream responseStream = response.GetResponseStream();
        StreamReader sR = new StreamReader(responseStream);

        sR.ReadToEnd();

        sR.Close();
        response.Close();
    }

Final code (working):

using (Stream responseStream = response.GetResponseStream()) {
            using (BinaryReader bR = new BinaryReader(responseStream)) {
                using (FileStream fsDest = new FileStream(destination, FileMode.Create)) {
                    BinaryWriter bw = new BinaryWriter(fsDest);
                    int readCount;
                    byte[] buffer = new byte[bytesPerChunk];

                    readCount = responseStream.Read(buffer, 0, bytesPerChunk);
                    bytesRead += Convert.ToUInt32(readCount);
                    updateProgress(bytesRead);

                    while (readCount > 0) {
                        bw.Write(buffer, 0, readCount);
                        readCount = responseStream.Read(buffer, 0, bytesPerChunk);
                        bytesRead += Convert.ToUInt32(readCount);
                        updateProgress(bytesRead);
                    }
                }
            }
        }
Community
  • 1
  • 1
Mansfield
  • 14,445
  • 18
  • 76
  • 112
  • Are you looking for [FtpWebRequest](http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx) class? – Renatas M. Aug 20 '12 at 13:43
  • @Reniuz I'm already using it! I'm just not sure of how to use it to download a file in chunks rather than all at once... – Mansfield Aug 20 '12 at 13:44
  • Cant see where you using it. I see just 2 file streams. – Renatas M. Aug 20 '12 at 13:49
  • @Reniuz zorry, I mean I'm using it in other parts of the application. I'm aware I need to use it for downloading the file, I'm just not sure how to split it up. I'll edit in the code I do have, even though it isn't much. – Mansfield Aug 20 '12 at 13:51
  • Ok. Almost everything stays same as current your code -all you need is to get stream to file via ftp. Instead of destination FileStream use FtpWebResponse.GetResponseStream(). [Here](http://msdn.microsoft.com/en-us/library/ms229711) is an example. Ill try to create pseudo code – Renatas M. Aug 20 '12 at 13:57

1 Answers1

2

Ok here is what you could try. This code is not tested. So if it contains errors and you get it work please edit answer or point me to mistakes.

static void chunkCopyFile(string source, string destination, int bytesPerChunk)
{
    uint bytesRead = 0;
    //Instead of this:
    //using (FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read)) {

    //...some necessary stuff...
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
    request.Method = WebRequestMethods.Ftp.DownloadFile;
    request.Credentials = new NetworkCredential ("anonymous","janeDoe@contoso.com");
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

    //Use this:
    using(Stream fs = response.GetResponseStream()){

        using (BinaryReader br = new BinaryReader(fs)) {
            using (FileStream fsDest = new FileStream(destination, FileMode.Create)) {
                BinaryWriter bw = new BinaryWriter(fsDest);
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];

                readCount = fs.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                   bw.Write(buffer, 0, readCount);
                   readCount = fs.Read(buffer, 0, bufferSize);
                   updateProgress(readCount);
                }
            }
        }
    }
}

References:

http://msdn.microsoft.com/en-us/library/ms229711

http://www.codeproject.com/Articles/17202/Simple-FTP-demo-application-using-C-Net-2-0 (Download method code)

Renatas M.
  • 11,694
  • 1
  • 43
  • 62