Victor Rodrigues
Victor Rodrigues

Reputation: 11731

FTP in C# returning corrupted file, why?

I have this method to transfer files using a FTP Server:

private void TransferNeededFiles(IEnumerable<string> filenames)
{
    foreach (var filename in filenames)
    {
        var request = WebRequest.Create(new Uri(@"ftp://{0}/{1}".Fill(Config.ServerUri, filename))) as FtpWebRequest;

        if (request != null)
        {
            request.Credentials = new NetworkCredential(Config.Username, Config.Password);

            request.Method = WebRequestMethods.Ftp.DownloadFile;
            using (var streamReader = new StreamReader(request.GetResponse().GetResponseStream()))
            {
                var fileStream = new FileStream(@"{0}/{1}".Fill(Config.DestinationFolderPath, filename), FileMode.Create);

                var writer = new StreamWriter(fileStream);
                writer.Write(streamReader.ReadToEnd());
                writer.Flush();
                writer.Close();

                fileStream.Close();
            }
        }
    }
}

A .gz file, included in the list of filenames, is always corrupted. When I try to copy from ftp using windows explorer, the file is not corrupted. Do you know what is happening?

Upvotes: 3

Views: 2670

Answers (2)

John Kugelman
John Kugelman

Reputation: 362147

Readers and Writers work with Unicode characters. To transfer binary data you want to be working with raw bytes, so you should be using plain Streams. You can copy from one stream to another with a loop like the following:

BufferedStream inputStream, outputStream;
byte[] buffer = new byte[4096];
int bytesRead;

while ((bytesRead = inputStream.Read(buffer)) > 0)
{
    outputStream.Write(buffer, 0, bytesRead);
}

A good thing about this is that it will also only use a fixed amount of memory rather than reading the entire file into memory at once.

Upvotes: 3

Joel Coehoorn
Joel Coehoorn

Reputation: 416149

The problem is this line:

writer.Write(streamReader.ReadToEnd());

StreamReader.ReadToEnd() returns a Unicode encoded string. You want something that will read the stream byte for byte.

Upvotes: 7

Related Questions