FtpWebRequest Download File - c#

The following code is intended to retrieve a file via FTP. However, I'm getting an error with it.
serverPath = "ftp://x.x.x.x/tmp/myfile.txt";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath);
request.KeepAlive = true;
request.UsePassive = true;
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(username, password);
// Read the file from the server & write to destination
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) // Error here
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
using (StreamWriter destination = new StreamWriter(destinationFile))
{
destination.Write(reader.ReadToEnd());
destination.Flush();
}
The error is:
The remote server returned an error: (550) File unavailable (e.g., file not found, no access)
The file definitely does exist on the remote machine and I am able to perform this ftp manually (i.e. I have permissions). Can anyone tell me why I might be getting this error?

I know this is an old Post but I am adding here for future reference. Here is a solution that I found:
private void DownloadFileFTP()
{
string inputfilepath = #"C:\Temp\FileName.exe";
string ftphost = "xxx.xx.x.xxx";
string ftpfilepath = "/Updater/Dir1/FileName.exe";
string ftpfullpath = "ftp://" + ftphost + ftpfilepath;
using (WebClient request = new WebClient())
{
request.Credentials = new NetworkCredential("UserName", "P#55w0rd");
byte[] fileData = request.DownloadData(ftpfullpath);
using (FileStream file = File.Create(inputfilepath))
{
file.Write(fileData, 0, fileData.Length);
file.Close();
}
MessageBox.Show("Download Complete");
}
}
Updated based upon excellent suggestion by Ilya Kogan

Easiest way
The most trivial way to download a binary file from an FTP server using .NET framework is using WebClient.DownloadFile:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.DownloadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
Advanced options
Use FtpWebRequest, only if you need a greater control, that WebClient does not offer (like TLS/SSL encryption, progress monitoring, ascii/text transfer mode, resuming transfers, etc). Easy way is to just copy an FTP response stream to FileStream using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
ftpStream.CopyTo(fileStream);
}
Progress monitoring
If you need to monitor a download progress, you have to copy the contents by chunks yourself:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
byte[] buffer = new byte[10240];
int read;
while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, read);
Console.WriteLine("Downloaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see:
FtpWebRequest FTP download with ProgressBar
Downloading folder
If you want to download all files from a remote folder, see
C# Download all files and subdirectories through FTP.

This paragraph from the FptWebRequest class reference might be of interest to you:
The URI may be relative or absolute.
If the URI is of the form
"ftp://contoso.com/%2fpath" (%2f is
an escaped '/'), then the URI is
absolute, and the current directory is
/path. If, however, the URI is of the
form "ftp://contoso.com/path", first
the .NET Framework logs into the FTP
server (using the user name and
password set by the Credentials
property), then the current directory
is set to /path.

I had the same issue!
My solution was to insert the public_html folder into the download URL.
Real file location on the server:
myhost.com/public_html/myimages/image.png
Web URL:
www.myhost.com/myimages/image.png

private static DataTable ReadFTP_CSV()
{
String ftpserver = "ftp://servername/ImportData/xxxx.csv";
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpserver));
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
// use the stream to read file from FTP
StreamReader sr = new StreamReader(responseStream);
DataTable dt_csvFile = new DataTable();
#region Code
//Add Code Here To Loop txt or CSV file
#endregion
return dt_csvFile;
}
I hope it can help you.

public void download(string remoteFile, string localFile)
{
private string host = "yourhost";
private string user = "username";
private string pass = "passwd";
private FtpWebRequest ftpRequest = null;
private FtpWebResponse ftpResponse = null;
private Stream ftpStream = null;
private int bufferSize = 2048;
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + remoteFile);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
FileStream localFileStream = new FileStream(localFile, FileMode.Create);
byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception) { }
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception) { }
return;
}

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath);
After this you may use the below line to avoid error..(access denied etc.)
request.Proxy = null;

FYI, Microsoft recommends not using FtpWebRequest for new development:
We don't recommend that you use the FtpWebRequest class for new development. For more information and alternatives to FtpWebRequest, see WebRequest shouldn't be used on GitHub.
The GitHub link directs to this SO page which contains a list of third-party FTP libraries, such as FluentFTP.

Related

Access denied on client.DownloadFile() [duplicate]

I am using .NET 4 C#. I am trying to upload and then download a ZIP file to (my) server.
For uploading I have
using (WebClient client = new WebClient())
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(MyUrl);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.EnableSsl = false;
request.Credentials = new NetworkCredential(MyLogin, MyPassword);
byte[] fileContents = null;
using (StreamReader sourceStream = new StreamReader(LocalFilePath))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
FtpWebResponse response = null;
response = (FtpWebResponse)request.GetResponse();
response.Close();
}
This seems to work, in that I get a file on the server of the right size.
1) How do I stream it, rather than load it into memory first? I will be uploading very large files.
And for downloading I have
using (WebClient client = new WebClient())
{
string HtmlResult = String.Empty;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(remoteFile);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.EnableSsl = false;
request.Credentials = new NetworkCredential(MyLogin, MyPassword);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
using (FileStream writer = new FileStream(localFilename, FileMode.Create))
{
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
}
}
2) Everything seems to work ... except when I try to unzip the downloaded ZIP file I get an invalid ZIP file.
Upload
The most trivial way to upload a binary file to an FTP server using .NET framework is using WebClient.UploadFile:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UploadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, transfer resuming, etc), use FtpWebRequest. Easy way is to just copy a FileStream to FTP stream using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
If you need to monitor an upload progress, you have to copy the contents by chunks yourself:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
byte[] buffer = new byte[10240];
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
ftpStream.Write(buffer, 0, read);
Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see:
How can we show progress bar for upload with FtpWebRequest
If you want to upload all files from a folder, see
Recursive upload to FTP server in C#.
Download
The most trivial way to download a binary file from an FTP server using .NET framework is using WebClient.DownloadFile:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.DownloadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, resuming transfers, etc), use FtpWebRequest. Easy way is to just copy an FTP response stream to FileStream using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
ftpStream.CopyTo(fileStream);
}
If you need to monitor a download progress, you have to copy the contents by chunks yourself:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
byte[] buffer = new byte[10240];
int read;
while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, read);
Console.WriteLine("Downloaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see:
FtpWebRequest FTP download with ProgressBar
If you want to download all files from a remote folder, see
C# Download all files and subdirectories through FTP.

C#: ftp upload is successful but dowloaded file is damaged

I'm using the code bellow to upload a zip file to to my ftp server:
string zipPath = #"d:\files\start.zip";
string ftpPath = ("ftp://######/start.zip");
WebRequest request = WebRequest.Create(ftpPath);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("######", "######");
StreamReader sourceStream = new StreamReader(zipPath);
byte[] fileContents = Encoding.Unicode.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
try
{
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse makeFileUploadResponse = (FtpWebResponse)request.GetResponse();
}
catch
{
MessageBox.Show("ftp failed!");
}
My zip archive is definitely valid (I can open it and extract it) but when I download the uploaded zip file, I got the error that archive is damaged.
Update 1: my source code is from MSDN article:How to: Upload Files with FTP
you should cast request to FtpWebRequest (as in that MSDN example)
and then specify request as binary (you're uploading binary file, not text).
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("aa");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
I can't say what the problem is but I can provide an alternate solution. You can use WebClient instead of WebRequest
string zipPath = #"d:\files\start.zip";
string ftpPath = ("ftp://######/start.zip");
WebClient ftpClient = new WebClient();
ftpClient.Credentials = new NetworkCredential("####", "######");
try{
ftpClient.UploadFile(ftpPath, WebRequestMethods.Ftp.AppendFile, zipPath);
}
catch(WebException ex){
MessageBox.Show("ftp failed");
}

ftpwebrequest.getresponse is throwing 550 access denied

I am trying to figure out how to get this file uploaded to my ftp server in C#. When it calls getResponse() on ftpwebrequest it is throwing an error that says "550 - access denied". I cannot figure out why. I can connect to the server with Filezilla just fine using the same credentials.
Here is my code that does the connection:
private void UploadFileToFTP(HttpPostedFile file, string server, string user, string pass)
{
string uploadUrl = server + file.FileName;
string uploadFileName = Path.GetFileName(file.FileName);
Stream streamObj = file.InputStream;
Byte[] buffer = new Byte[file.ContentLength];
streamObj.Read(buffer, 0, buffer.Length);
streamObj.Close();
streamObj = null;
try
{
SetMethodRequiresCWD();
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
//ftp.Method = WebRequestMethods.Ftp.MakeDirectory;
ftp.Method = WebRequestMethods.Ftp.UploadFile;
ftp.UsePassive = true;
ftp.Credentials = new NetworkCredential(user, pass);
FtpWebResponse CreateForderResponse = (FtpWebResponse)ftp.GetResponse();
if (CreateForderResponse.StatusCode == FtpStatusCode.PathnameCreated)
{
string ftpUrl = string.Format("{0}/{1}", uploadUrl, uploadFileName);
FtpWebRequest requestObj = FtpWebRequest.Create(ftpUrl) as FtpWebRequest;
requestObj.KeepAlive = true;
requestObj.UseBinary = true;
requestObj.Method = WebRequestMethods.Ftp.UploadFile;
requestObj.Credentials = new NetworkCredential(user, pass);
Stream requestStream = requestObj.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
requestObj = null;
}
}
catch (WebException e)
{
String status = ((FtpWebResponse)e.Response).StatusDescription;
}
}
OK, I tinkered around with this some more after reading through the comments here. I went into my Kaspersky settings and disabled scanning of port 20 and 21. Boom! File is there. Now it is coming across empty for some reason, so I will investigate that or come back for some help here! :)

best way to upload a binary file using FTP [duplicate]

I am using .NET 4 C#. I am trying to upload and then download a ZIP file to (my) server.
For uploading I have
using (WebClient client = new WebClient())
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(MyUrl);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.EnableSsl = false;
request.Credentials = new NetworkCredential(MyLogin, MyPassword);
byte[] fileContents = null;
using (StreamReader sourceStream = new StreamReader(LocalFilePath))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
FtpWebResponse response = null;
response = (FtpWebResponse)request.GetResponse();
response.Close();
}
This seems to work, in that I get a file on the server of the right size.
1) How do I stream it, rather than load it into memory first? I will be uploading very large files.
And for downloading I have
using (WebClient client = new WebClient())
{
string HtmlResult = String.Empty;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(remoteFile);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.EnableSsl = false;
request.Credentials = new NetworkCredential(MyLogin, MyPassword);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
using (FileStream writer = new FileStream(localFilename, FileMode.Create))
{
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
}
}
2) Everything seems to work ... except when I try to unzip the downloaded ZIP file I get an invalid ZIP file.
Upload
The most trivial way to upload a binary file to an FTP server using .NET framework is using WebClient.UploadFile:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UploadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, transfer resuming, etc), use FtpWebRequest. Easy way is to just copy a FileStream to FTP stream using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
If you need to monitor an upload progress, you have to copy the contents by chunks yourself:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
byte[] buffer = new byte[10240];
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
ftpStream.Write(buffer, 0, read);
Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see:
How can we show progress bar for upload with FtpWebRequest
If you want to upload all files from a folder, see
Recursive upload to FTP server in C#.
Download
The most trivial way to download a binary file from an FTP server using .NET framework is using WebClient.DownloadFile:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.DownloadFile(
"ftp://ftp.example.com/remote/path/file.zip", #"C:\local\path\file.zip");
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, resuming transfers, etc), use FtpWebRequest. Easy way is to just copy an FTP response stream to FileStream using Stream.CopyTo:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
ftpStream.CopyTo(fileStream);
}
If you need to monitor a download progress, you have to copy the contents by chunks yourself:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip");
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(#"C:\local\path\file.zip"))
{
byte[] buffer = new byte[10240];
int read;
while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, read);
Console.WriteLine("Downloaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see:
FtpWebRequest FTP download with ProgressBar
If you want to download all files from a remote folder, see
C# Download all files and subdirectories through FTP.

How to upload a file in a non-default directory using FTPWEBREQUEST?

I face an issue while I try to upload a file in a non-default directory of the server.
When I use "ftp://server01/autofile/test.zip", the file gets uploaded without any issues since autofile is the default directory.
But when I use the below code, I get an exception which says "The remote server returned an error: (550) File unavailable (e.g., file not found, no access).". Shown below is the piece of code I use.
string inputfilepath = "E:\\Test\\test.ZIP";
string ftpfullpath = "ftp://server01/../bcp/ftp/ftpsftiu/test.ZIP";
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpfullpath);
ftp.Method = WebRequestMethods.Ftp.UploadFile;
ftp.Credentials = new NetworkCredential("Username", "password");
ftp.UsePassive = true;
ftp.KeepAlive = true;
ftp.UseBinary = true;
FileStream fs = File.OpenRead(inputfilepath);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream reqStream = ftp.GetRequestStream();
But I can open the above non-default directory path(ftp://server01/../bcp/ftp/ftpsftiu/test.ZIP) through the Run Command of windows.
How do I upload my file to this non-default directory of the server through C# code?
please help me to fix this.
Thanks in advance!!!
With regards,
Shadu
It worked for me if I put another slash after the server (//server//).
I did (also) fully qualify the output path name.
The static GetCread() is a method call into a home-grown class.
Example:
static void Main(string[] args)
{
string strSystem = "MAPS";
FtpWebRequest req = (FtpWebRequest)WebRequest.Create("ftp://" + strSystem +"//export/home/hinest/science/trans/fred.txt");
req.Credentials = CGetCred.GetCred(strSystem);
req.Method = WebRequestMethods.Ftp.UploadFile;
FtpWebResponse resp = (FtpWebResponse)req.GetResponse();
StreamWriter fileOut = new StreamWriter(req.GetRequestStream());
StreamReader fileIn = new StreamReader(#"c:\science\"+strSystem+".txt");
while (!fileIn.EndOfStream)
{
fileOut.WriteLine(fileIn.ReadLine());
}
fileIn.Close();
fileOut.Close();
resp.Close();
}

Categories