Reputation: 11731
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
Reputation: 362147
Reader
s and Writer
s work with Unicode characters. To transfer binary data you want to be working with raw bytes, so you should be using plain Stream
s. 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
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