Reputation: 10590
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?
Upvotes: 2
Views: 4243
Reputation: 202692
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)
Upvotes: 1
Reputation: 635
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;
}
}
Upvotes: 0
Reputation: 54
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.
Upvotes: 0