I am trying to file download from remote machine with FTP in c# but it doesn't work. when i came GetResponse Method with f10, threw the exception. its says:"unable to connect to remote server", it looks like about connection problem but its not.
when i create request in the code ContentType and PreAuthenticate is threw an exception and said:"System.NotSupportedException"
How can i fix this? Any ideas?
Here's the Connection Info for FTP.
private static string host = #"ftp://XXX.XX.XXX.XX/";
private static string user = "XXXXXXXX";
private static string pass = "XXXXXXXX";
private static string localfile = #"E:/Files/Attachment";
private static string remoteFile = #"D:/log/stdlog.6.txt";
And then FTP class
public class FtpServer
{
private string host = null;
private string user = null;
private string pass = null;
private FtpWebRequest ftpRequest = null;
private FtpWebResponse ftpResponse = null;
private Stream ftpStream = null;
private int bufferSize = 2048;
/* Construct Object */
public FtpServer(string hostIP, string userName, string password) { host = hostIP; user = userName; pass = password; }
public void Download(string remoteFile, string localFile)
{
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 ex)
{
Console.WriteLine(ex.ToString());
}
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return;
}
}
Unable to connect to remote server could be several reasons.
1) you could be mistakenly typing the server address and pointing to a non-existing address.
2) The server is temporarily shut or down and you cannot access it.
3) You typed in wrong credentials for the server.
Either way, I suggest you to implement using statement in your code rather then using close() on every stream:
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
using (ftpResponse = (FtpWebResponse)ftpRequest.GetResponse())
{
using (ftpStream = ftpResponse.GetResponseStream())
{
using (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 ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
ftpRequest = null;
Related
In my code I want to download a specific File from FTP-Server to my local machine.I am getting an exception like below
System.InvalidCastException: Unable to cast object of type: 'System.Net.HttpWebRequest' to type 'System.Net.FtpWebRequest' at FTPapp.ftpdownload.Download(String remoteFile, String localFile)
My code:
namespace FTPapp
{
public partial class ftpdownload : Form
{
private string Host = null;
private string user = null;
private string pass = null;
private string SSH = null;
private FtpWebRequest ftprequest = null;
private FtpWebResponse ftpresponse = null;
private Stream ftpStream = null;
private int buffersize = 2048;
public ftpdownload()
{
InitializeComponent();
}
public ftpdownload(string hostIP, string username, string password ,string SSHkey)
{
Host = hostIP;
user = username;
pass = password;
SSH = SSHkey;
}
public void Download(string remoteFile, string localFile)
{
try
{
ftprequest = (FtpWebRequest)FtpWebRequest.Create(Host + "/" + remoteFile);
ftprequest.Credentials = new NetworkCredential(user, pass ,SSH);
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];
`enter code here` int bytesRead = ftpStream.Read(byteBuffer, 0, buffersize);
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, buffersize);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
localFileStream.Close();
ftpStream.Close();
ftpresponse.Close();
ftprequest= null;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
txtServer.Text = "http://ftpsite.com";
txtUsername.Text = "";
txtPassword.Text = #"";
txtFilename.Text = #"";
txtSSHKey.Text = "";
}
private void BtnDownload_Click(object sender, EventArgs e)
{
ftpdownload ftp = new ftpdownload("http://ftpsite.com" ,"","","");
ftp.Download(#"Remotepath", #"local path");
}
}
}
We cannot be sure that the link is FTP Uri without checking it.
As specified in microsoft documentation, you need to use ftp:// before the hostname, like: ftp://contoso.com/someFile.txt.
So, how to solve your problem?
First of all, you should add ftp:// to your link. After that you may create a Uri object and check whether it's scheme is Uri.UriSchemeFtp. If not, return.
I've created an application that uploads files to a remote FTP server. If the credentials (address, username, password, etc.) are wrong I want to to throw an error. As of right now it never does. What is wrong with my code? When the credentials are correct it does successfully upload.
here is the class I am using:
public void upload(string remoteFile, string localFile)
{
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.UploadFile;
ftpStream = ftpRequest.GetRequestStream();
FileStream localFileStream = File.OpenRead(localFile);
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
localFileStream.Close();
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return;
}
and where I'm calling the upload function in the form:
On button click =
ftp ftpClient = new ftp(#"ftp://weburl.com/", "user", "password");
UploadToFTP("testing/file.txt" , #"C:\file.txt");
void UploadToFTP(string FTPfolder, string LocalFolder)
{
try
{
ftpClient.upload(FTPfolder, LocalFolder);
Messagebox.Show("Uploaded Successfully!");
}
catch (Exception ex)
{
Messagebox.Show(ex.ToString());
}
}
From my comment if there is an error, its spitting it to the console, but isn't waiting for readkey, so the console is disappearing, you never catch another exception in your call because the catch in the function is handling the error. Inside the function replace Console.WriteLine with Messagebox.Show to see the caught errors
public void upload(string remoteFile, string localFile)
{
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.UploadFile;
ftpStream = ftpRequest.GetRequestStream();
FileStream localFileStream = File.OpenRead(localFile);
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { Messagebox.Show(ex.ToString()); }
localFileStream.Close();
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex) { Messagebox.Show(ex.ToString()); }
return;
}
Rewrite your upload function is eating the exception.
I would rewrite your catch block this way:
try
{
// ....
}
catch (WebException webEx)
{
string message = string.Empty;
if (webEx.Response.GetType() == typeof(FtpWebResponse))
{
FtpWebResponse response = (FtpWebResponse)webEx.Response;
message = string.Format("{0} - {1}", response.StatusCode, response.StatusDescription);
} else
{
message = webEx.Message;
}
throw new Exception(message);
}
I'm newbie to FTP.I am trying to write to a file in FTP using StreamWriter.Once after writing to the file,i dont want to close the stream as i have some work which has to be done.Later after some 1 hour,if i try to write using the same streamWriter i get the above error.
Below is my code snippet
public void WriteToFTP()
{
bool isConnectionEstablished = false;
StreamWriter stream = null;
try
{
for (int i = 1; i < 5; i++)
{
string message = string.Format("File - {0}.", i.ToString());
if (!isConnectionEstablished)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("My FTP path"));
request.Credentials = new NetworkCredential("asdf", "asdf#123");
request.Proxy = null;
request.UseBinary = true;
request.ConnectionGroupName = string.Empty;
request.UsePassive = true;
request.EnableSsl = false;
isConnectionEstablished = true;
stream = new StreamWriter(request.GetRequestStream()) { AutoFlush = true };
}
stream.WriteLine(message);//Here i am getting the error for the i = 2(after doing my work)
//Doing work which may take more than 1 hour.
}
}
catch (Exception exe)
{
//The Error "Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host" is being caught here.
}
finally
{
if (stream != null)
stream.Close();
}
}
you must set timout to infinity,-1 is the value for infinity, see this example:
FtpWebRequest reqFTP;
string fileName = #"c:\downloadDir\localFileName.txt";
FileInfo downloadFile = new FileInfo(fileName);
string uri = "ftp://ftp.myftpsite.com/ftpDir/remoteFileName.txt";
FileStream outputStream = new FileStream(fileName, FileMode.Append);
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.KeepAlive = false;
reqFTP.Timeout = -1;
reqFTP.UsePassive = true;
reqFTP.Credentials = new NetworkCredential("userName", "passWord");
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
readCount = ftpStream.Read(buffer, 0, bufferSize);
Console.WriteLine("Connected: Downloading File");
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize);
Console.WriteLine(readCount.ToString());
}
ftpStream.Close();
outputStream.Close();
response.Close();
Console.WriteLine("Downloading Complete");
I am trying to upload image and video using code below, there is no issue with image upload using ftp, but when I am uploading video I get the following error
Error
The underlying connection was closed: An unexpected error occurred on a receive.
Following is the code I am using to upload
Code
try
{
string uploadFileName = Path.GetFileName(FU_Video.FileName);
uploadFileName = "video." + uploadFileName.Split('.')[1];
using (WebClient client = new WebClient())
{
string ftpAddres = "ftp://username:pasword#url-path" + fullname;
if (!GetAllFilesList(ftpAddres, "username", "password"))
{
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpAddres);
ftp.Method = WebRequestMethods.Ftp.MakeDirectory;
ftp.KeepAlive = false;
FtpWebResponse response = (FtpWebResponse)ftp.GetResponse();
}
client.UploadData(new Uri(ftpAddres + "/" + uploadFileName), FU_Video.FileBytes);
}
and here is the stack trace.
stack Trace
at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request)
at System.Net.WebClient.UploadData(Uri address, String method, Byte[] data)
at System.Net.WebClient.UploadData(Uri address, Byte[] data)
at MentorMentee.SignUp.signup.btn_VidPreview_Click(Object sender, EventArgs e) in I:\VS Projects\code\MentorMentee1\MentorMentee\SignUp\signup.aspx.cs:line 469
after searching I read to make connection alive false, but I am getting error on line client.UploadData(uri,byte[]);
please let me know what is wrong with my code? as video is uploaded on ftp, but I get error.
I remember having similar issue, but don't remember exactly what made it work. Here is the code that works well for me:
public void Upload(Stream stream, string fileName)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
try
{
FtpWebRequest ftpRequest = CreateFtpRequest(fileName);
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream requestSream = ftpRequest.GetRequestStream())
{
Pump(stream, requestSream);
}
var ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
}
catch (Exception e)
{
throw new FtpException(
string.Format("Failed to upload object. fileName: {0}, stream: {1}", fileName, stream), e);
}
}
private FtpWebRequest CreateFtpRequest(string fileName)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
string serverUri = string.Format("{0}{1}", ftpRoot, fileName);
var ftpRequest = (FtpWebRequest)WebRequest.Create(serverUri);
ftpRequest.Credentials = new NetworkCredential(configuration.UserName, configuration.Password);
ftpRequest.UsePassive = true;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = false;
return ftpRequest;
}
private static void Pump(Stream input, Stream output)
{
var buffer = new byte[2048];
while (true)
{
int bytesRead = input.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
break;
}
output.Write(buffer, 0, bytesRead);
}
}
How do you copy a file on an FTP server? My goal is to copy ftp://www.mysite.com/test.jpg to ftp://www.mysite.com/testcopy.jpg. To rename a file, I would use:
var request = (FtpWebRequest)WebRequest.Create("ftp://www.mysite.com/test.jpg");
request.Credentials = new NetworkCredential(user, pass);
request.Method = WebRequestMethods.Ftp.Rename;
request.RenameTo = "testrename.jpg"
request.GetResponse().Close();
FtpWebResponse resp = (FtpWebResponse)request.GetResponse();
However, there is no Method for copying files. How would you do copy a file?
Try this:
static void Main(string[] args)
{
CopyFile("countrylist.csv", "MySample.csv", "username", "password#");
}
public static bool CopyFile(string fileName, string FileToCopy, string userName, string password)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.mysite.net/" + fileName);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(userName, password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
Upload("ftp://ftp.mysite.net/" + FileToCopy, ToByteArray(responseStream), userName, password);
responseStream.Close();
return true;
}
catch
{
return false;
}
}
public static Byte[] ToByteArray(Stream stream)
{
MemoryStream ms = new MemoryStream();
byte[] chunk = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
{
ms.Write(chunk, 0, bytesRead);
}
return ms.ToArray();
}
public static bool Upload(string FileName, byte[] Image, string FtpUsername, string FtpPassword)
{
try
{
System.Net.FtpWebRequest clsRequest = (System.Net.FtpWebRequest)System.Net.WebRequest.Create(FileName);
clsRequest.Credentials = new System.Net.NetworkCredential(FtpUsername, FtpPassword);
clsRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
System.IO.Stream clsStream = clsRequest.GetRequestStream();
clsStream.Write(Image, 0, Image.Length);
clsStream.Close();
clsStream.Dispose();
return true;
}
catch
{
return false;
}
}
This downloads the file to a stream, and then uploads it.
FtpWebRequest is a lightweight class. Microsoft felt it should be used by simple client to download and delete the files once the client is finish.
I guess you can't really do this with FTP. What you can do is download the file you want to copy and then upload it with a new name. For example:
try
{
WebClient request = new WebClient();
request.Credentials = new NetworkCredential(user, pass);
byte[] data = request.DownloadData(host);
MemoryStream file = new MemoryStream(data);
Upload(data);
}
catch (Exception ex)
{
}
...
private void Upload(byte[] buffer)
{
try
{
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(newname);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(user, pass);
Stream reqStream = request.GetRequestStream();
reqStream.Write(buffer, 0, buffer.Length);
reqStream.Close();
var resp = (FtpWebResponse)request.GetResponse();
}
catch (Exception ex)
{
}
}
In our project we did someting like this
// pass parameters according to your need,
// the below code is done in a hard coded manner for clarity
public void Copy()
{
// from where you want to copy
var downloadRequest = (FtpWebRequest)WebRequest.Create("ftp://www.mysite.com/test.jpg");
downloadRequest.Credentials = new NetworkCredential("userName", "passWord");
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
var ftpWebResponse = (FtpWebResponse)downloadRequest.GetResponse();
var downloadResponse = ftpWebResponse.GetResponseStream();
int buffLength = 2048;
byte[] byteBuffer = new byte[buffLength];
// bytes read from download stream.
// from documentation: When overridden in a derived class, reads a sequence of bytes from the
// current stream and advances the position within the stream by the number of bytes read.
int bytesRead = downloadResponse.Read(byteBuffer, 0, buffLength);
// the place where you want the file to go
var uploadRequest = (FtpWebRequest)WebRequest.Create("ftp://www.mysite.com/testCopy.jpg");
uploadRequest.Credentials = new NetworkCredential("userName", "passWord");
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;
var uploadStream = uploadRequest.GetRequestStream();
if (bytesRead > 0)
{
while (bytesRead > 0)
{
uploadStream.Write(byteBuffer, 0, bytesRead);
bytesRead = downloadResponse.Read(byteBuffer, 0, buffLength);
}
}
uploadStream.Close();
uploadStream.Dispose();
downloadResponse.Close();
ftpWebResponse.Close();
((IDisposable)ftpWebResponse).Dispose();
}