I'm developing a system that need to download binary files from a server folder. In here I will check before downloading whether they are in my local folder.so I need to get list of the *.bin files.
I have tried code in below, but it generate list all the files that on server folder.
private string[] GetRemoteFileList()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri(_remoteHost));
request.Credentials = new NetworkCredential(_remoteUser, _remotePass);
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string FileNames = reader.ReadToEnd();
string[] Files = Regex.Split(FileNames, "\r\n");
return Files;
}
What I need is filter out only *.bin files. How can I achieve this?
What have you tried?
You have now in Files an array of all files in the current directory. Why don't you filter that list? For example:
return Files.Where(
f => f.EndsWith(".bin", StringComparison.OrdinalIgnoreCase)
).ToList();
Related
I have a file folder in my FTP server and I want to fill a ComboBox with the contents inside of that folder. How would I go about doing this?
string result = string.Empty;
//Request location and server name---------->
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://*******" +"/" + "Products" + "/");
//Lists directory
request.Method = WebRequestMethods.Ftp.ListDirectory;
// set credentials
request.Credentials = new NetworkCredential("user1","1234");
//initialize response
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
//reader to read response
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
combobox1.Text = FTP_Server();
//data from file.
result = reader.ReadToEnd();
reader.Close();
response.Close();
Thanks! I didn't know if this was even possible!
Read the listing by lines:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://example.com/remote/path/");
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential("username", "password");
comboBox1.BeginUpdate();
try
{
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
comboBox1.Items.Add(reader.ReadLine());
}
}
}
finally
{
comboBox1.EndUpdate();
}
Downloading whole listing to a string and splitting it afterwards (as suggested by the other answer) can be pretty ineffective, if there's lot of entries.
Without knowing the exact format of your response string, my instinct would be to split the response string:
string files[] = result.Split("\r\n");
Then to iterate over the individual files, adding them to your combobox1's Items:
// Depending on how many items you're adding, you may wish to prevent a repaint until the operation is finished
combobox1.BeginUpdate();
foreach(string file in files)
{
combobox1.Items.Add(file);
}
combobox1.EndUpdate();
That should take care of it for you! There is some excellent (and exhaustive) documentation on MSDN as well, which will often contain some usage examples to help you out further: https://msdn.microsoft.com/en-us/library/system.windows.forms.combobox(v=vs.110).aspx#Examples
Note that, if you end up wanting to display information from a different FTP response, you'll have to clear the combobox1 like so first: combobox1.Items.Clear();
I have an FTP and I want to know the files that has been added today.
(in my business rules, there is no update to the files, so the files could be added and then can't be modified or removed at all).
I tried this:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://172.28.4.7/");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("{0} {1}", "ftp://172.28.4.7/", response.LastModified);
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
But, as expected, in the console I got the date of the last modifying.
Could you help me please to know the last added files?
You have to retrieve timestamps of remote files to select those you want (today's files).
Unfortunately, there's no really reliable and efficient way to retrieve timestamps using features offered by .NET framework as it does not support FTP MLSD command. The MLSD command provides listing of remote directory in a standardized machine-readable format. The command and the format is standardized by the RFC 3659.
Alternatives you can use, that are supported by the .NET framework:
the ListDirectoryDetails method (FTP LIST command) to retrieve details of all files in a directory and then you deal with FTP server specific format of the details
*nix format: Parsing FtpWebRequest ListDirectoryDetails line
DOS/Windows format: C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response
the GetDateTimestamp method (FTP MDTM command) to individually retrieve timestamps for each file. Advantage is that the response is standardized by RFC 3659 to YYYYMMDDHHMMSS[.sss]. Disadvantage is that you have to send a separate request for each file, what can be quite inefficient.
const string uri = "ftp://example.com/remote/path/file.txt";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
request.Method = WebRequestMethods.Ftp.GetDateTimestamp;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("{0} {1}", uri, response.LastModified);
This is what the answer by #tretom shows.
Alternatively you can use a 3rd party FTP client implementation that supports the modern MLSD command or that can directly download files given time constraint.
For example WinSCP .NET assembly supports both MLSD and time constraints.
There's even an example for your specific task: How do I transfer new/modified files only?
The example is for PowerShell, but translates to C# easily:
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "ftp.example.com",
UserName = "username",
Password = "password",
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Download today's times
TransferOptions transferOptions = new TransferOptions();
transferOptions.FileMask = "*>=" + DateTime.Today.ToString("yyyy-MM-dd");
session.GetFiles(
"/remote/path/*", #"C:\local\path\", false, transferOptions).Check();
}
(I'm the author of WinSCP)
First you have to Get All Directory Details using "ListDirectoryDetails" :
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails
Get the Response in string[] .
Than Check if the string[] For File or Directory by checking "DIR" text in String[] items.
And after getting the Filenames From string[] , Again Request For "File Creation Date" of Each and Every File using :
ftpRequest.Method = WebRequestMethods.Ftp.GetDateTimestamp;
So, You can Get The File Added Date of your FTP Server.
a possible synchronous solution (it might be useful for someone):
a data container type:
public class Entity
{
public DateTime uploadDate { get; set; }
public string fileName { get; set; }
}
and the Lister lass:
public class FTPLister
{
private List<Entity> fileList = new List<Entity>();
public List<Entity> ListFilesOnFTP(string ftpAddress, string user, string password)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddress);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(user, password);
List<string> tmpFileList = new List<string>();
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
tmpFileList.Add(reader.ReadLine());
}
}
Uri ftp = new Uri(ftpAddress);
foreach (var f in tmpFileList)
{
FtpWebRequest req = (FtpWebRequest)WebRequest.Create(new Uri(ftp, f));
req.Method = WebRequestMethods.Ftp.GetDateTimestamp;
req.Credentials = new NetworkCredential(user, password);
using (FtpWebResponse resp = (FtpWebResponse)req.GetResponse())
{
fileList.Add(new Entity() { fileName=f, uploadDate=resp.LastModified });
}
}
fileList = fileList.Where(p => p.uploadDate>=DateTime.Today && p.uploadDate<DateTime.Today.AddDays(1)).ToList();
return fileList;
}
}
Hi all is it possible to copy a file from the path obtained to the domain, I tried as follows but I am getting an exception as uri formats are not supported.. So can some one help me how to copy the file
string filePath = "D:\\Folder\\filename.jpg";
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo.Exists)
{
path = "http://WWW.somedomain.com";
string temppath = path + "/Temp" + "/" + fileInfo.Name;
if (!File.Exists(temppath))
{
var uri = new Uri(temppath);
File.Copy(filePath, uri.AbsoluteUri);
}
You want to check the existence of file on the server. This is not possible using File.Exist method as it doesn't supports the URI. This method expect the relative path and checked the existence on machine (physical location).
In this case you should use WebRequest and get the response from the server. If server returns 404 then your file doesn't exist on the serve or you can check the Content Length.
WebRequest request = WebRequest.Create(new Uri(temppath));
request.Method = "HEAD";
WebResponse response = request.GetResponse()
var contentLength = response.ContentLength;
if (contentLength < 0)
{
// file doesn't exist.
}
Now I know how to copy files from one directory to another, this is really simple.
But now I need to do the same with files from FTP server. Can you give me some example how to get file from FTP while changing its name?
Take a look at How to: Download Files with FTP or downloading all files in directory ftp and c#
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","janeDoe#contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
Console.WriteLine("Download Complete, status {0}", response.StatusDescription);
reader.Close();
reader.Dispose();
response.Close();
Edit
If you want to rename file on FTP Server take a look at this Stackoverflow question
Easiest way
The most trivial way to download a binary file from an FTP server using .NET framework is using WebClient.DownloadFile.
It takes an URL to the source remote file and a path to the target local file. So you can use a different name for the local file, if you need that.
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
If you need greater control, that WebClient does not offer (like TLS/SSL encryption, ASCII mode, active mode, 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);
}
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.
I've just written a simple FTP console app to upload files on a local server to a remote FTP site. Everything seems to be working fine until it comes to actually transferring the file. For some reason instead of uploading the file to the specified FTP site it stores the entire file locally with no in the Debug folder with no file type and named the same as the ip of the FTP site. I'm thinking that this has something to do with Visual Studio's debugging. Can anybody give me some guidance on this?
Here is the code I'm using to attempt to upload each file in a string array to the FTP site.
private static void Upload(string ftpServer, string userName, string password, string filename)
{
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential(userName, password);
client.UploadFile(ftpServer, "STOR", filename);
}
}
Use this method instead of that one,it worked for me.
//Directory sands for Remote Server Directory ,it must create if dir not exist
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://serverIP/directory/file");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential ("username","password");
// Copy the contents of the file to the request stream.
StreamReader sourceStream = new StreamReader("testfile.txt");
byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
source- http://msdn.microsoft.com/en-us/library/ms229715.aspx
Try this way instead: http://msdn.microsoft.com/en-us/library/ms229715.aspx