1

I am trying to transfer files between a couple of sites and I'm using FtpWebRequest to download the file from site A and upload it to site B.

The problem I'm facing is when I am downloading the file I'm not getting more then 8820 bytes of data.

Heres the code I am using:

public FtpFile Download(string path)
{
  string fullpath = ConstructFullpath(path);

  FtpWebRequest request = (FtpWebRequest)WebRequest.Create(fullpath);
  request.Method = WebRequestMethods.Ftp.DownloadFile;
  // login
  request.Credentials = new NetworkCredential(Username, Password);  

  FtpWebResponse response = (FtpWebResponse)request.GetResponse();
  Stream responseStream = request.GetResponse().GetResponseStream();

  byte[] data = new byte[20000];
  int length = responseStream.Read(data, 0, data.Length);
  responseStream.Close();

  FtpFile file = new FtpFile(path, data, length);
  return file;
}

public bool Upload(FtpFile file)
{
  if (!DirectoryExists(GetDirectory(file.Path)))
  {
    CreateDirectory(GetDirectory(file.Path));
  }

  string fullpath = ConstructFullpath(file.Path);
  FtpWebRequest request = (FtpWebRequest)WebRequest.Create(fullpath);
  request.Method = WebRequestMethods.Ftp.UploadFile;
  request.Credentials = new NetworkCredential(Username, Password);


  Stream stream = request.GetRequestStream();
  stream.Write(file.Data, 0, file.Length);
  stream.Close();

  FtpWebResponse response = (FtpWebResponse)request.GetResponse();
  return true;
}

The First image shows the source directory. The second image shows the destination directory.

The source web directory

The destination web directory I have tried saving the files locally and have the same result.

Rollcredit
  • 453
  • 2
  • 5
  • 13

1 Answers1

4

You're only calling Read once:

byte[] data = new byte[20000];
int length = responseStream.Read(data, 0, data.Length);
responseStream.Close();

There's no guarantee that all the data will be read in a single call, and you should never rely on it doing so. You should loop round (e.g. copying the data into a MemoryStream) until Read returns 0.

If you're using .NET 4, Stream.CopyTo makes this easy:

MemoryStream ms = new MemoryStream();
responseStream.CopyTo(ms);

Note that you should also use using statements instead of closing resources explicitly, and that includes the FtpWebResponse.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • And for those not using 4.0 see the answer to [FtpWebRequest Download File Incorrect Size](http://stackoverflow.com/questions/3196226/ftpwebrequest-download-file-incorrect-size). – Joshua Drake Mar 07 '12 at 19:40