When I want to get the size of a file on my ftp server I gets nothing.
Anyone see a problem in the code?
it seems to me that method is good
the class :
public string getFileSize(string fileName)
{
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + fileName);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
StreamReader ftpReader = new StreamReader(ftpStream);
string fileInfo = null;
try { while (ftpReader.Peek() != -1) { fileInfo = ftpReader.ReadToEnd(); } }
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
return fileInfo;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return "";
}
the process :
ftp ftpClientCheckFile = new ftp(#"ftp://******.******.fr", "***********", "********");
string ftpfileSize = ftpClientCheckFile.getFileSize(fileName);
if (ftpfileSize == localfilesize)
{
this.Invoke(new Action(() => { MessageBox.Show(this, "*********", "***", MessageBoxButtons.OK, MessageBoxIcon.Information); }));
ftpClientCheckFile = null;
}
else
{
this.Invoke(new Action(() => { MessageBox.Show(this, "***** ", "*******", MessageBoxButtons.OK, MessageBoxIcon.Information); }));
}
Thanks for help.
You need to use the ContentLength property to get the file size
Console.WriteLine(ftpResponse.ContentLength.ToString());
Some ftp servers don't support getfilesize so you will have to use ListDirectoryDetails
Related
I have 1 issues when i try too send file using FTP from Azure WebJobs.
This throw alternatly 'The remote server returned an error: (530) Not logged in.', my code work great in localhost (on dev computer).
I have read all off thoses Post but i didn't find a way :
FTPWebRequest 530 Error: Not Logged in issue
FTP The remote server returned an error: (530) Not logged in
Fetching files from FTP server via Azure webjobs
Ftp to external server in azure webjob not working
Other but i have only 1 webjobs in my app service and the CPU was at 30% when the jobs running ..
File download from FTP fails only in Azure web app
Edit :
Code Make Directory
FtpWebRequest reqFTP = null;
Stream ftpStream = null;
string[] subDirs = directory.Split('/');
string currentDir = publishUrl;
foreach (string subDir in subDirs)
{
try
{
currentDir = currentDir + "/" + subDir;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(currentDir);
reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
reqFTP.UseBinary = true;
//reqFTP.UsePassive = true;
//reqFTP.KeepAlive = true;
reqFTP.Credentials = new NetworkCredential(userName, userPWD);
FtpWebResponse response = (FtpWebResponse)await reqFTP.GetResponseAsync();
ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
//directory already exist I know that is weak but there is no way to check if a folder exist on ftp...
}
}
Code Send File :
try
{
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(userName, userPWD);
client.UploadFile(publishUrl, "STOR", localFileName);
return true;
}
}
catch (Exception exception)
{
//Console.Error.Write(exception.Message);
Console.WriteLine(exception.Message);
return false;
}
And log when i run code in Azure WebApp WebJobs (Failed) :
https://pastebin.com/vgTxqT5p
And log when i run code in local machine (Work Great) :
https://pastebin.com/hBpum8T0
I think the workaround was on WebJobs app style and normal function wasn't waiting. I'm going to change my code to use Async Await method for all my WebJobs program.
Any have a way ?
Thx in advance.
Bad way (and i didn't Like this) but it's work..... :
Change the Make Directory Function like this :
public static void MakeFTPDir(string publishUrl, string userName, string userPWD, string directory)
{
FtpWebRequest reqFTP = null;
Stream ftpStream = null;
string[] subDirs = directory.Split('/');
string currentDir = publishUrl;
foreach (string subDir in subDirs)
{
bool isNotCreated = true;
int iTentative = 0;
currentDir = currentDir + "/" + subDir;
while (isNotCreated)
{
iTentative++;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(currentDir);
reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.KeepAlive = true;
reqFTP.Credentials = new NetworkCredential(userName, userPWD);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
ftpStream = response.GetResponseStream();
ftpStream.Close();
response.Close();
}
catch(WebException webException)
{
FtpWebResponse excWebResponse = (FtpWebResponse)webException.Response;
if(excWebResponse.StatusCode == FtpStatusCode.NotLoggedIn)
{
Console.WriteLine("WebException ==> NotLoggedIn >> Tentative :" + iTentative);
isNotCreated = true;
}
else
{
Console.WriteLine(webException.Message);
isNotCreated = false;
}
}
catch (Exception exception)
{
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
if (response.StatusCode == FtpStatusCode.NotLoggedIn)
{
Console.WriteLine("Exception ==> NotLoggedIn >> Tentative :" + iTentative);
isNotCreated = true;
}
else
{
Console.WriteLine(exception.Message);
isNotCreated = false;
}
}
}
}
}
Change the send file function like this
public static bool SendFtpFile(string publishUrl, string userName, string userPWD, string localFileName)
{
bool isNotCreated = true;
int iTentative = 0;
while (isNotCreated)
{
iTentative++;
try
{
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(userName, userPWD);
client.UploadFile(publishUrl, "STOR", localFileName);
return true;
}
}
catch (WebException webException)
{
FtpWebResponse excWebResponse = (FtpWebResponse)webException.Response;
if (excWebResponse.StatusCode == FtpStatusCode.NotLoggedIn)
{
Console.WriteLine("WebException ==> NotLoggedIn >> Tentative :" + iTentative);
isNotCreated = true;
}
else
{
Console.WriteLine(webException.Message);
return false;
}
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
return false;
}
}
return true;
}
Change the IfFileExistOnServer :
public static bool CheckIfFileExistsOnServer(string publishUrl, string userName, string userPWD, string fileName)
{
bool isNoCheck = true;
int iTentative = 0;
string azureBotUrl = publishUrl + "/" + fileName;
while (isNoCheck)
{
iTentative++;
try
{
var request = (FtpWebRequest)WebRequest.Create(azureBotUrl);
request.Credentials = new NetworkCredential(userName, userPWD);
request.UseBinary = true;
request.UsePassive = true;
request.KeepAlive = true;
request.Method = WebRequestMethods.Ftp.GetFileSize;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
return true;
}
catch (WebException webException)
{
FtpWebResponse excWebResponse = (FtpWebResponse)webException.Response;
if (excWebResponse.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
return false;
if (excWebResponse.StatusCode == FtpStatusCode.NotLoggedIn)
{
Console.WriteLine("WebException ==> NotLoggedIn >> Tentative :" + iTentative);
isNoCheck = true;
}
else
{
return false;
}
}
}
return false;
}
And Change RenameFileOnServer :
public static bool RenameFileOnServer(string publishUrl, string userName, string userPWD, string sourceFileName, string newFileName)
{
bool isNoRenameFile = true;
int iTentative = 0;
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
string azureBotUrl = publishUrl + "/" + sourceFileName;
while (isNoRenameFile)
{
iTentative++;
try
{
ftpRequest = (FtpWebRequest)WebRequest.Create(azureBotUrl);
ftpRequest.Credentials = new NetworkCredential(userName, userPWD);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.Rename;
ftpRequest.RenameTo = newFileName.Split('\\')[newFileName.Split('\\').Length - 1];
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ftpRequest = null;
return true;
}
catch (WebException webException)
{
FtpWebResponse excWebResponse = (FtpWebResponse)webException.Response;
if (excWebResponse.StatusCode == FtpStatusCode.NotLoggedIn)
{
Console.WriteLine("WebException ==> NotLoggedIn >> Tentative :" + iTentative);
isNoRenameFile = true;
}
else
{
return false;
}
Console.WriteLine(webException.Message);
}
catch (Exception)
{
return false;
}
}
return false;
}
I'm waiting a call from Ms Azure Support ...
I need to create file or directory on ftp via C# (in Unity engine). I tried to upload the file this way:
public void upload(string remoteFile, string file_content)
{
try
{
string address = host + #"/текст.txt";
Debug.Log(address); // gives a normal address in Unicode
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(address);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.ContentLength = file_content.Length;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
byte[] byteBuffer = System.Text.Encoding.Unicode.GetBytes(file_content);
try
{
using (ftpStream = ftpRequest.GetRequestStream())
{
ftpStream.Write(byteBuffer, 0, byteBuffer.Length);
Debug.Log(Convert.ToString(byteBuffer));
}
}
catch (Exception ex)
{
ErrorScene.error = "Local Error: 1. " + ex.ToString(); SceneManager.LoadScene("ErrorScene", LoadSceneMode.Single);
}
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex)
{
ErrorScene.error = "Local Error: 2. " + ex.ToString(); SceneManager.LoadScene("ErrorScene", LoadSceneMode.Single);
}
return;
}
And after this function call in ftp creates a file named ?????.txt.
Similarly with directories.
Is there a way to do this?
Thanks in advance.
I am using this code to connect my server and downloading the files. It is working fine.
public void downloadFile(object args)
{
writeStream = null;
response = null;
reader = null;
int dataLength = 0;
try
{
Array argArray = new object[3];
argArray = (Array)args;
ProgressBar progressBar1 = (ProgressBar)argArray.GetValue(0);
Label lbProgress = (Label)argArray.GetValue(1);
FTPInfo ftpInfo = (FTPInfo)argArray.GetValue(2);
string ipAddress = ftpInfo.IpAddress;
string path = ftpInfo.Path;
string fileName = ftpInfo.FileName;
path = Regex.Replace(path, "_.", "_e");
fileName = Regex.Replace(fileName, "_.", "_e");
string uri = null;
if (path.Equals(""))
{
uri = ipAddress + fileName;
}
else
{
uri = ipAddress + path + "/" + fileName;
}
string[] temp = ipAddress.Split('/');
string ip = "mchmultimedia.com";
string userName = ftpInfo.UserName;
string password = ftpInfo.Password;
downloadedData = new byte[0];
ftp = new FTPClass(path);
ftp.FtpServer = ip;
ftp.FtpUsername = userName;
ftp.FtpPassword = password;
ftp.FtpLogin();
dataLength = (int)ftp.GetFileSize(fileName);
Logger.LogDebugMessage("DataLength :" + dataLength.ToString());
ftp.CloseConnection();
FtpWebRequest request = FtpWebRequest.Create(uri) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(userName, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
//Set up progress bar
UpdateProgressBarValue(progressBar1, 0);
SetProgressBarMaxValue(progressBar1, dataLength);
response = request.GetResponse() as FtpWebResponse;
reader = response.GetResponseStream();
if (!Directory.Exists(GlobalClass.ZIPPED_FOLDER))
Directory.CreateDirectory(GlobalClass.ZIPPED_FOLDER);
writeStream = new FileStream(GlobalClass.ZIPPED_FOLDER + "\\" + fileName, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = 0;
Logger.LogDebugMessage("Before while :" + dataLength.ToString());
while (true)
{
Application.DoEvents();
bytesRead = reader.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
try
{
try
{
reader.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("reader close if bytesRead ==00", ex);
}
try
{
response.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("response close if bytesRead ==00", ex);
}
try
{
writeStream.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("writeStream close if bytesRead ==00", ex);
}
}
catch (Exception ex)
{
}
UpdateProgressBarValue(progressBar1, progressBar1.Maximum);
Application.DoEvents();
break;
}
else
{
writeStream.Write(buffer, 0, bytesRead);
if (progressBar1.Value + bytesRead <= progressBar1.Maximum)
{
totalBytesRead = progressBar1.Value + bytesRead;
int percentage = (int)((double)totalBytesRead / dataLength * 100);
UpdateProgressBarValue(progressBar1, totalBytesRead);
SetText(lbProgress, "File download " + percentage.ToString() + " % completed");
if (percentage == 100)
{
if (totalBytesRead == dataLength)
{
try
{
try
{
reader.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("reader close if percentage==100", ex);
}
try
{
response.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("response close if percentage==100", ex);
}
try
{
writeStream.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("writeStream close if percentage==100", ex);
}
}
catch (Exception ex)
{
}
SetText(lbProgress, "File download successfully completed,Please wait...");
unzipFile(fileName);
}
}
RefreshProgressBar(progressBar1);
Application.DoEvents();
}
}
}
}
catch (System.Threading.ThreadAbortException ex)
{
if (thread != null)
{
thread.Abort();
}
Logger.LogErrorMessage("ThreadAbortException", ex);
}
catch (Exception ex)
{
Logger.LogErrorMessage("Exception there was an error connecting", ex);
Logger.ReportBug("There was an error connecting to the FTP Server.", ex);
}
finally
{
try
{
try
{
reader.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("read finally", ex);
}
try
{
response.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("resonse finally", ex);
}
try
{
writeStream.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("writeStream finally", ex);
}
}
catch (Exception ex)
{
}
}
}
But client needs it to be secure FTP. So I tried by setting
request.EnableSsl = true;
as specified in Differences between SFTP and "FTP over SSH"
And it throws:
The remote server returned an error: (500) Syntax error, command unrecognized.
You are obviously required to use the SFTP protocol.
The FtpWebRequest class does not support the SFTP protocol. There's no support at all for SFTP in standard .NET libraries. See SFTP Libraries for .NET.
You current code is trying to connect with the FTP over TLS protocol to the FTP server. That is an another way of securing "file transfer" session. But this particular FTP server does not support it (hence the "500 Syntax error, command unrecognized" error).
So you have to rewrite your code to use the SFTP protocol.
That's unfortunately a completely different code.
i'm using the below method to upload files from local server to FTP server, here i'm creating a new connection and initiating a new session each and every file uploading and closing the same. how to achieve this in single initiated session in c#.
this is my code
public bool UploadTempFilesToFTP()
{
string[] fileList;
try
{
ConfiguredValues conObj = new ConfiguredValues();
conObj.PickTheValuesFromConfigFile();
fileList = Directory.GetFiles(conObj.tempPath);
foreach (string FileName in fileList)
{
FtpWebRequest upldrequest = (FtpWebRequest)FtpWebRequest.Create(conObj.tempOutboundURL + FileName);
upldrequest.UseBinary = true;
upldrequest.KeepAlive = false;
upldrequest.Timeout = -1;
upldrequest.UsePassive = true;
upldrequest.Credentials = new NetworkCredential(conObj.user, conObj.pass);
upldrequest.Method = WebRequestMethods.Ftp.UploadFile;
string destinationAddress = conObj.tempPath;
FileStream fs = File.OpenRead(destinationAddress + FileName);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream requestStr = upldrequest.GetRequestStream();
requestStr.Write(buffer, 0, buffer.Length);
requestStr.Close();
requestStr.Flush();
FtpWebResponse response = (FtpWebResponse)upldrequest.GetResponse();
response.Close();
File.Delete(destinationAddress + FileName);
}
Console.WriteLine("Uploaded Successfully to Temp folder");
return true;
}
catch (Exception ex)
{
Console.WriteLine("Upload failed. {0}", ex.Message);
return false;
}
}
it's weird that i answer an old question but i try almost everything to upload multiple files to ftp with no luck while the solution is very simple and effective, using LOOPING - foreach solved the issue for me i use the below function to Upload the files in one simple step..
public void Uploadbulkftpfiles(string[] list)
{
bool ife;// is folder exists
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftpsite.com/folder");
request.Credentials = new NetworkCredential("Username", "Password");
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
ife = true;
}
catch (Exception)
{
ife = false;
}
/////////////////////////////////////////////begin of upload process
if (ife)//the folder is already exists
{
foreach (var str in list)
{
try
{
FtpWebRequest requestUP2 = (FtpWebRequest)WebRequest.Create("ftp://ftpsite.com/folder" + str);
requestUP2.Credentials = new NetworkCredential("UserName", "Password");
requestUP2.Method = WebRequestMethods.Ftp.UploadFile;
requestUP2.KeepAlive = false;
requestUP2.UsePassive = true;
using (Stream fileStream = File.OpenRead("ftp://ftpsite.com/folder" + str))
using (Stream ftpStream = requestUP2.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
}
catch (Exception ex1)
{
MessageBox.Show(ex1.Message);
}
}
}
else if (!ife)
{
//CREATE THE FOLDER
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp:ftpsite/folder");
request.Credentials = new NetworkCredential("UserName", "Password");
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
}
catch (Exception excr) { MessageBox.Show(excr.Message); }
//UPLOAD THE FILES
foreach (var str in list)
{
try
{
FtpWebRequest requestUP2 = (FtpWebRequest)WebRequest.Create("ftp://ftpsite.com/folder" + str);
requestUP2.Credentials = new NetworkCredential("UserName", "Password");
requestUP2.Method = WebRequestMethods.Ftp.UploadFile;
requestUP2.KeepAlive = false;
requestUP2.UsePassive = true;
using (Stream fileStream = File.OpenRead("ftp://ftpsite.com/folder" + str))
using (Stream ftpStream = requestUP2.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
}
catch (Exception ex1)
{
MessageBox.Show(ex1.Message);
}
}
}
}
The ftp protocol is intended to works on request basis.
You start a request with a method (in your case UploadFile).
The only thing you can do is to KeepAlive your request to avoid connection closing
upldrequest.KeepAlive = true;
on every request you create except the last one. This will make a login only the first FTPWebRequest.
Then when you create the last FTPWebRequest, set
upldrequest.KeepAlive = false;
and it will close the connection when done.
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);
}