how to make function supports parameters for this
public List<string> getfiles(string FTPhostname, string FTPpath,string FTPusername,string FTPpassword,string extension)
{
'request to ftp hostname
'get response from
'list all directories and files
'search for spesified extension files
}
any way for this ?
here is the solution a function that return List
public List<string> getfiles(string FTPhostname, string FTPpath,string FTPusername,string FTPpassword,string extension)
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://" + FTPhostname + "/" + FTPpath );
ftpRequest.Credentials = new NetworkCredential(FTPusername , FTPpassword );
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
List<string> results = new List<string>();
string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
if (line.Contains(extension)) {
line = streamReader.ReadLine();
results.Add(line);}
else {line = streamReader.ReadLine(); }
}
streamReader.Close();
return results;
}
then call this function for ex: png files
String[] txtfounds= getfiles("ftp.piacton.com", "/Public/Software/Official/LightField/Archives/", "anonymous", "k3tnel31#k.com", ".png").ToArray();
if you want to add this result to lisbox :
listBox1.DataSource = txtfounds;
There is an error, you need to do the
results.Add(line);
before you call the
results.Add(line);
to get the correct files.
Related
This unit test should be passing and I can't figure out why it's not. The code works in my main controller, so I know it does work. But I feel like it's assessing differently in my unit test.
I have tried various other asserts, with the exception of the false Booleans. I don't want a false comparison.
[TestMethod]
public void DownloadFileNames()
{
// Arrange
string ftpBase = "myfiles.com/public/doc";
string fileName = "10408c";
Search model = new Search();
model.FileName = fileName;
//A string to hold the base FTP address:
Search searchResults = new Search();
List<string> fnl = new List<string>();
var uriBuilder = new UriBuilder();
// Act
uriBuilder.Scheme = "ftp";
uriBuilder.Host = ftpBase;
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uriBuilder.Uri);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
List<string> files = new List<string>();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
files.Add(reader.ReadLine());
reader.Close();
responseStream.Dispose();
//Loop through the resulting file names.
foreach (string folder in files)
{
if (folder.IndexOf(".") < 1)
{
var childDirectory = uriBuilder.Uri + folder + "/";
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(childDirectory);
request.Method = WebRequestMethods.Ftp.ListDirectory;
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream);
string result = reader.ReadToEnd();
reader.Close();
responseStream.Dispose();
searchResults.Messages = result;
if (result.Contains(model.FileName))
{
if (!model.FileName.Contains(".dat"))
{
model.FileName = model.FileName.Replace(".dat", "");
fnl.Add(ftpBase.Replace(ftpBase, uriBuilder.Uri + folder + "/") + model.FileName + ".dat");
}
else
{
fnl.Add(ftpBase.Replace(ftpBase, uriBuilder.Uri + folder + "/") + model.FileName);
}
//UpdateFile(fnl);
searchResults.Messages = "file found";
break;
}
else
{
searchResults.Messages = "file not found";
}
}
else
{
//searchResults.Messages = "Just Files";
}
}
// Assert
Assert.AreEqual(fnl, "ftp://myfiles.com/public/doc/cor/10408c.dat");
}
I expect the fnl and the string to match. But the Expected gives this code instead.
"Expected:. "
I suspect I am missing something, but since I am still green on unit testing, I have no idea what it is I am missing.
If you have nothing constructive to say, please just pass on any remarks. I have looked for answers to my question, but nothing I found seemed to relate to my issue enough to be of any help.
fnl is a string list (ie: List<string>) while the other is just a raw String
There is no way those two completely different objects will match given the shown code
Assuming that the list contains only one string then just use the index from the list
//...
Assert.AreEqual(fnl[0], "ftp://myfiles.com/public/doc/cor/10408c.dat");
And just for readability
//...
string expected = "ftp://myfiles.com/public/doc/cor/10408c.dat";
string actual = fnl[0];
Assert.AreEqual(expected, actual);
I want to write a C# that:
Access the FTP with username and password
Goes to a certain folder
Sees what files aren't there from my PC folder and upload them.
My idea:
I have a folder called "mods" in my PC and another folder called "mods" in the FTP, so instead of opening the "FileZilla" software I want to write a C# that connects to the FTP and check what files aren't there.
Thank you so much!
you can list your file inftp server like this and do a comparaiosn with list file of mod dir
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(uri);
ftpRequest.Credentials =new NetworkCredential("anonymous","janeDoe#contoso.com");
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
List<string> directories = new List<string>();
string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
directories.Add(line);
line = streamReader.ReadLine();
}
streamReader.Close();
There's no magic way, with a pure .NET framework (its FtpWebRequest class). You have to code it.
List the FTP folder
List the local folder
Find the missing files
Upload them one by one
void SynchronizeLocalAndFtpDirectory(
string localPath, string remoteUri, NetworkCredential credentials)
{
List<string> remoteFiles = new List<string>();
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(remoteUri);
request.Credentials = credentials;
request.Method = WebRequestMethods.Ftp.ListDirectory;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
while (!reader.EndOfStream)
{
remoteFiles.Add(reader.ReadLine());
}
}
IEnumerable<string> localFiles =
Directory.GetFiles(localPath).Select(path => Path.GetFileName(path));
IEnumerable<string> missingFiles = localFiles.Except(remoteFiles);
foreach (string filename in missingFiles)
{
Console.WriteLine("Uploading missing file {0}", filename);
string remoteFileUri = remoteUri + filename;
string localFilePath = Path.Combine(localPath, filename);
FtpWebRequest uploadRequest = (FtpWebRequest)WebRequest.Create(remoteFileUri);
uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;
uploadRequest.Credentials = credentials;
using (Stream targetStream = uploadRequest.GetRequestStream())
using (Stream sourceStream = File.OpenRead(localFilePath))
{
byte[] buffer = new byte[10240];
int read;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
{
targetStream.Write(buffer, 0, read);
}
}
}
}
Use the function like:
SynchronizeLocalAndFtpDirectory(
#"C:\local\mods", "ftp://ftp.example.com/remote/mods/",
new NetworkCredential("username", "password"));
(Do not forget the trailing slash in the URI).
Or use 3rd party FTP library that supports synchronization.
For example with the WinSCP .NET assembly, this is as easy as a single call to Session.SynchronizeDirectories.
And it will not only upload missing file, but also update out-of-the-date files and optionally delete orphan files.
void SynchronizeLocalAndFtpDirectory(
string localPath, string remotePath, SessionOptions sessionOptions)
{
using (Session session = new Session())
{
session.Open(sessionOptions);
session.SynchronizeDirectories(
SynchronizationMode.Remote, localPath, remotePath, false).Check();
}
}
Use it like:
SessionOptions sessionOptions = new SessionOptions()
{
Protocol = Protocol.Ftp,
HostName = "ftp.example.com",
UserName = "username",
Password = "password",
};
SynchronizeLocalAndFtpDirectory(#"C:\local\mods", "/remote/mods", sessionOptions);
(I'm the author of WinSCP)
The code i'm using now:
string[] Files = GetFileList();
ArrayList arrDirectories = new ArrayList();
if (Files != null)
{
foreach (string dir in Files)
{
arrDirectories.Add(dir);
}
}
if (!arrDirectories.Contains(dirName))
{
Sync(dirName, reqFTP, response, ftpStream);
}
The method GetFileList:
public string[] GetFileList()
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
WebResponse response = null;
StreamReader reader = null;
try
{
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + f.Host + "/"));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(f.Username, f.Password);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = false;
response = reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}
result.Remove(result.ToString().LastIndexOf('\n'), 1);
return result.ToString().Split('\n');
}
catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
if (response != null)
{
response.Close();
}
downloadFiles = null;
return downloadFiles;
}
}
What i'm getting in the end in arrDirectories is all the files and directories and sub directories from my ftp server. The problem is that each file,directory,and sub directory are in it's own index.
For example i see in index 0 in arrDirectories: test
Then in index 1 i see: testsub
Then in index 2 i see: test.jpg
But in fact test is under root directory and testsub is under test and test.jpg is under testsub.
The problem is that when i check if directory already exist:
if (!arrDirectories.Contains(dirName))
If it's a single directory for example test then there is no problem.
But if the directory i want to check if exist is a sub directory like test/testsub
Then it will never find it even if it is exist on my ftp server.
So in case i have to check a directories like test/testsub or test/test1/test2/test3...what should i change first in the GEtFileList method ? And then how to loop over the arrDirectories maybe need a recursive ?
try using this code'
first get the directory structure into string array:
string[] Directories = Directory.GetDirectories(#"c:\windows\Temp", "*.*", SearchOption.AllDirectories);
then use linq to checkout if your directory exsists
bool DirectoryExists = !String.IsNullOrEmpty(Directories.Where(d => d.ToLower().Contains(#"Directory Name...")).FirstOrDefault());
Yes, you're right, the simplest way - call GetFileList() recursively
And put results into list, not into string
Here is your modified code
static public void GetFileList(List<string> list,string sroot)
{
WebResponse response = null;
StreamReader reader = null;
try
{
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + Host+sroot));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(Username, Password);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails ;
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = false;
response = reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
string file;
while (!reader.EndOfStream )
{
if (line.StartsWith("-"))
{
file = sroot + "/" + line.Substring(57);
list.Add(file);
}
else if (line.StartsWith("d"))
{
file = sroot + "/" + line.Substring(57);
list.Add(file+"/");
GetFileList(list, file);
}
line = reader.ReadLine();
}
}
catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
if (response != null)
{
response.Close();
}
}
return;
}
Calls method ListDirectoryDetails instead of ListDirectory to
distinguish directories and files
Parses result to get file name from file details (am not sure it is always the end of line starting from pos. 57 :-)
Calls self for each found folder
The criteria of the end of stream is EndOfStream :-)
Here is the call
List<string> filelist = new List<string>();
GetFileList(filelist, "");
foreach (string s in filelist )
Console.WriteLine(s.Substring(1));
All folders have "/" at the end (feel free to do not include folders into list).
It's easy to build local file list using method from previous answer.
Im trying to make a program that lets you check the availibility of a specific file extention on that ftp server and then sort the ones out that have the files on.
this is how i tried to do it so far:
string path;
path = "ftp://" + textBox1.Text + "/";
string[] files = System.IO.Directory.GetFiles(path, "*.txt", SearchOption.AllDirectories);
FtpWebRequest ftpRequest =
(FtpWebRequest)WebRequest.Create("ftp://ftp.freebsd.org/pub/FreeBSD/");
ftpRequest.Credentials = new NetworkCredential("anonymous", "k3rnel31#k.com");
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
List<string> filestxt = new List<string>();
string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
if (line.Contains(".txt"))
{
MessageBox.Show(line);
line = streamReader.ReadLine();
filestxt.Add(line);
}
else
{
line = streamReader.ReadLine();
}
}
streamReader.Close();
Hi and thanks for looking!
Background
I need to pull the file locations (path and filename) for all files at a given FTP address.
For files on a mapped network or local drive, this code would work:
foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*",
SearchOption.AllDirectories)
{
//do stuff with each file found
}
But this will NOT work over an FTP connection. I have already found this MS documentation which covers the establishing of an FTPWebRequest, but it does not show me how to loop through each file found (in all nested directories as well).
I am using C# within a forms app.
Question
How do I accomplish this:
foreach(string fileName f in Directory.GetFiles("C\\:SomeDirectory"), "*.*",
SearchOption.AllDirectories)
{
//do stuff with each file found
}
With an FTP connection?
Many thanks!!
UPDATE / Final Answer
Special thanks to #sunk for getting this going. I made a minor tweek to his code that makes it fully recursive so that it can drill into nested folders. Here is the final code:
//A list that holds all file locations in all folders of a given FTP address:
List<string> fnl= new List<string>();
//A string to hold the base FTP address:
string ftpBase = "ftp://[SOME FTP ADDRESS]";
//A button-click event. Can be a stand alone method as well
private void GetFileLocations(object sender, EventArgs e)
{
//Get the file names from the FTP location:
DownloadFileNames(ftpBase);
//Once 'DownloadFileNames' has run, we have populated 'fnl'
foreach(var f in fnl)
{
//do stuff
}
}
//Gets all files in a given FTP address. RECURSIVE METHOD:
public void DownloadFileNames(string ftpAddress)
{
string uri = ftpAddress;
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
reqFTP.Credentials = new NetworkCredential("pella", "PellaWA01!");
reqFTP.EnableSsl = false;
reqFTP.KeepAlive = false;
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
List<string> files = new List<string>();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
files.Add(reader.ReadLine());
reader.Close();
responseStream.Dispose();
//Loop through the resulting file names.
foreach (var fileName in files)
{
var parentDirectory = "";
//If the filename has an extension, then it actually is
//a file and should be added to 'fnl'.
if (fileName.IndexOf(".") > 0)
{
fnl.Add(ftpAddress.Replace("ftp://pella.upload.akamai.com/140607/pella/", "http://media.pella.com/") + fileName);
}
else
{
//If the filename has no extension, then it is just a folder.
//Run this method again as a recursion of the original:
parentDirectory += fileName + "/";
try
{
DownloadFileNames(ftpAddress + parentDirectory);
}
catch (Exception)
{
//throw;
}
}
}
}
First of all, you have to get the files name local on your machine using FTPWebRequest.
WebRequestMethods.Ftp.ListDirectory;
then use foreach {};
Here is the code:-
public List<string> DownloadFileNames()
{
string uri = "ftp://" + ftpServerIP + "/";
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.EnableSsl = true;
reqFTP.KeepAlive = false;
reqFTP.UseBinary = true;
reqFTP.UsePassive = Settings.UsePassive;
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
List<string> files = new List<string>();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
files.Add(reader.ReadLine());
reader.Close();
responseStream.Dispose();
return files;
}
Now you have the List:-
List<string> FileNameList = DownloadFileNames();
foreach (var fileName in FileNameList)
{
}
the ListDirectoryDetails command used in the example just returns a string. You will have to manually parse it to build a list of files and subdirectories.
Found at http://social.msdn.microsoft.com/Forums/en/ncl/thread/079fb811-3c55-4959-85c4-677e4b20bea3
string[] files = GetFileList();
foreach (string file in files)
{
Download(file);
}
public string[] GetFileList()
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
WebResponse response = null;
StreamReader reader = null;
try
{
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/"));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = false;
response = reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}
// to remove the trailing '\n'
result.Remove(result.ToString().LastIndexOf('\n'), 1);
return result.ToString().Split('\n');
}
catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
if (response != null)
{
response.Close();
}
downloadFiles = null;
return downloadFiles;
}
}
private void Download(string file)
{
try
{
string uri = "ftp://" + ftpServerIP + "/" + remoteDir + "/" + file;
Uri serverUri = new Uri(uri);
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return;
}
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + remoteDir + "/" + file));
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Proxy = null;
reqFTP.UsePassive = false;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(localDestnDir + "\" + file, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
writeStream.Close();
response.Close();
}
catch (WebException wEx)
{
MessageBox.Show(wEx.Message, "Download Error");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Download Error");
}
}