Retrieving creation date of file (FTP)
WebRequestMethods.Ftp.ListDirectory
returns a "short listing" of all the files in an FTP directory. This type of listing is only going to provide file names - not additional details on the file (like permissions or last modified date).
Use WebRequestMethods.Ftp.ListDirectoryDetails
instead. This method will return a long listing of files on the FTP server. Once you've retrieved this list into the names
variable, you can split the names
variable into an array based on an end of line character. This will result in each array element being a file (or directory) name listing that includes the permissions, last modified date owner, etc...
At this point, you can iterate over this array, examine the last modified date for each file, and decide whether to download the file.
I hope this helps!!
Retrieve date modified of a file from an FTP Server
If you use download.file
you get an html representation of the directory which you can parse with the xml2 package.
read_ftp <- function(url)
{
tmp <- tempfile()
download.file(url, tmp, quiet = TRUE)
html <- xml2::read_html(readChar(tmp, 1e6))
file.remove(tmp)
lines <- strsplit(xml2::xml_text(html), "[\n\r]+")[[1]]
lines <- grep("(\\d{2}/){2}\\d{4}", lines, value = TRUE)
result <- read.table(text = lines, stringsAsFactors = FALSE)
setNames(result, c("Date", "Time", "Size", "File"))
}
Which allows you to just do this:
read_ftp("ftp://ftp.FreeBSD.org/pub/FreeBSD/")
#> Date Time Size File
#> 1 05/07/2015 12:00AM 4,259 README.TXT
#> 2 04/22/2020 08:00PM 35 TIMESTAMP
#> 3 04/22/2020 08:00PM Directory development
#> 4 04/22/2020 10:00AM 2,325 dir.sizes
#> 5 11/12/2017 12:00AM Directory doc
#> 6 11/12/2017 12:00AM Directory ports
#> 7 04/22/2020 08:00PM Directory releases
#> 8 11/09/2018 12:00AM Directory snapshots
Created on 2020-04-22 by the reprex package (v0.3.0)
How to order files received from FTP by the creation date in C#?
So after I found out that I needed to retrieve a detailed list of the files the sort problem was easy to solve. I just needed to call
Array.Sort(arrayOfFiles)
Here is the working code:
try
{
/* Create an FTP Request */
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(URI);
/* Log in to the FTP Server with the User Name and Password Provided */
ftpRequest.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
/* When in doubt, use these options */
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Specify the Type of FTP Request */
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
/* Establish Return Communication with the FTP Server */
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
/* Establish Return Communication with the FTP Server */
ftpStream = ftpResponse.GetResponseStream();
/* Get the FTP Server's Response Stream */
StreamReader ftpReader = new StreamReader(ftpStream);
/* Store the Raw Response */
string directoryRaw = null;
/* Read Each Line of the Response and Append a Pipe to Each Line for Easy Parsing */
try
{
while (ftpReader.Peek() != -1)
{
directoryRaw += ftpReader.ReadLine() + "|";
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
/* Resource Cleanup */
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
/* Return the Directory Listing as a string Array by Parsing 'directoryRaw' with the Delimiter you Append (I use | in This Example) */
try
{
string[] directoryList = directoryRaw.Split("|".ToCharArray());
Array.Sort(directoryList);
return directoryList;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
/* Return an Empty string Array if an Exception Occurs */
return new string[] { "" };
Retrieve modified DateTime of a file from an FTP Server
Until we see the output from this particular FTP server (they are all different) for directory listings, here's a path you can follow:
library(curl)
library(stringr)
Get the raw directory listing:
con <- curl("ftp://ftp.FreeBSD.org/pub/FreeBSD/")
dat <- readLines(con)
close(con)
dat
## [1] "-rw-rw-r-- 1 ftp ftp 4259 May 07 16:18 README.TXT"
## [2] "-rw-rw-r-- 1 ftp ftp 35 Sep 09 21:00 TIMESTAMP"
## [3] "drwxrwxr-x 9 ftp ftp 11 Sep 09 21:00 development"
## [4] "-rw-r--r-- 1 ftp ftp 2566 Sep 09 10:00 dir.sizes"
## [5] "drwxrwxr-x 28 ftp ftp 52 Aug 23 10:44 doc"
## [6] "drwxrwxr-x 5 ftp ftp 5 Aug 05 04:16 ports"
## [7] "drwxrwxr-x 10 ftp ftp 12 Sep 09 21:00 releases"
Filter out the directories:
no_dirs <- grep("^d", dat, value=TRUE, invert=TRUE)
no_dirs
## [1] "-rw-rw-r-- 1 ftp ftp 4259 May 07 16:18 README.TXT"
## [2] "-rw-rw-r-- 1 ftp ftp 35 Sep 09 21:00 TIMESTAMP"
## [3] "-rw-r--r-- 1 ftp ftp 2566 Sep 09 10:00 dir.sizes"
Extract just the timestamp and filename:
date_and_name <- sub("^[[:alnum:][:punct:][:blank:]]{43}", "", no_dirs)
date_ane_name
## [1] "May 07 16:18 README.TXT"
## [2] "Sep 09 21:00 TIMESTAMP"
## [3] "Sep 09 10:00 dir.sizes"
Put them into a data.frame
:
do.call(rbind.data.frame,
lapply(str_match_all(date_and_name, "([[:alnum:] :]{12}) (.*)$"),
function(x) {
data.frame(timestamp=x[2],
filename=x[3],
stringsAsFactors=FALSE)
})) -> dat
dat
## timestamp filename
## 1 May 07 16:18 README.TXT
## 2 Sep 09 21:00 TIMESTAMP
## 3 Sep 09 10:00 dir.sizes
You still need to convert the timestamp to a POSIXct
but that's trivial.
This particular example is dependent on that system's FTP directory listing response. Just change the regexes for yours.
WinSCP get file creation date
Is this what you are looking for?
Dim sessionOptions As New WinSCP.SessionOptions With { ... initialize your ftp parameters here ... }
Using session As WinSCP.Session = New WinSCP.Session
session.Open(sessionOptions)
Dim fileInfos As WinSCP.RemoteDirectoryInfo = session.ListDirectory(ftpFolder)
For Each ftpFile As WinSCP.RemoteFileInfo In fileInfos.Files
' Here you get the file date:
Dim fileDate As Date = ftpFile.LastWriteTime
Next
End Using
How to read the creation date from a string[] with FTP ListDirectoryDetails?
Not really an answer to the question, but at first I ended up with making a separate call to the FTP server to get the LastModified
datetime of the file(not a good solution) and added them to a list of file names with creation dates.
In the end it turned out that the creation date of the file is no longer important for the project, so I just used the standard FTP ListDirectory
.
Related Topics
Why Does the Contains() Operator Degrade Entity Framework's Performance So Dramatically
Posting JSON Data to ASP.NET MVC
Performance of Calling Delegates VS Methods
How to Remove All White Space from the Beginning or End of a String
What Is Point of Ssl If Fiddler 2 Can Decrypt All Calls Over Https
How Best to Read a File into List<String>
Serialize Property as Xml Attribute in Element
Is String.Format as Efficient as Stringbuilder
How to Run a Task on a Custom Taskscheduler Using Await
Getting Http Status Code Number (200, 301, 404, etc.) from Httpwebrequest and Httpwebresponse
Best Regular Expression for Email Validation in C#
How to Use Microsoft.Office.Interop.Excel on a MAChine Without Installed Ms Office
Httpcontext.Current.Session Is Null When Routing Requests
How to Call Generic Method with a Given Type Object