locked
FTP ListDirectoryDetails not returning data/time consistently

    Frage

  • When I use ListDirectoryDetails it sometimes returns the string with the Month and Date or Month and Year. 

    I'm am using this call for one directory on an FTP server with 15 files.  Roughly half of them come back one way or the other.  It's consistent but I end up having to use GetDateTimeStamp on each file to retrieve the full date and time on each file. 

    How can I make ListDirectoryDetails always return the full date and time - including the year.

    Example of what I'm getting now:
    -rw-r--r-- 1 ftp ftp        5592560 Feb 26 18:53 DamonJenkinsA_84_C_CTS.dds
    -rw-r--r-- 1 ftp ftp        1398256 Feb 12 19:44 GaryMadewA_63_C_CTS.dds
    -rw-r--r-- 1 ftp ftp         699192 Feb 02  2010 JeffCodyA_26_C_CTS.dds
    -rw-r--r-- 1 ftp ftp          90112 Feb 02  2010 JoeExlineA_39_C_CTS.dds
    -rw-r--r-- 1 ftp ftp         699192 Feb 02  2010 JoeExlineB_39_C_CTS.dds
    -rw-r--r-- 1 ftp ftp             58 Feb 02  2010 JoeExlineB_39_C_CTS.txt
    -rw-r--r-- 1 ftp ftp        1398256 Feb 12 11:22 JoeSzotA_33_C_CTS.dds
    -rw-r--r-- 1 ftp ftp         699192 Feb 02  2010 JohnKennedyA_71_C_CTS.dds
    -rw-r--r-- 1 ftp ftp             58 Feb 02  2010 JohnKennedyA_71_C_CTS.txt
    -rw-r--r-- 1 ftp ftp        2796344 Feb 08 16:00 MikeHebbA_32_C_CTS.dds
    -rw-r--r-- 1 ftp ftp             63 Feb 08 16:00 MikeHebbA_32_C_CTS.txt
    -rw-r--r-- 1 ftp ftp         699192 Feb 17 19:11 MikeKoonA_45_C_CTS.dds
    -rw-r--r-- 1 ftp ftp             60 Feb 17 19:11 MikeKoonA_45_C_CTS.txt
    drwxr-xr-x 1 ftp ftp              0 Feb 26 18:53 misc
    -rw-r--r-- 1 ftp ftp        2796344 Feb 22 10:59 RayMossA_24_C_CTS.dds

    Code:

    request = (

    FtpWebRequest)WebRequest.Create(FTPServer + "/" + FTPDir + folder);

    request.Credentials =

    new NetworkCredential(FTPUserID, FTPPwd);

    request.Method =

    WebRequestMethods.Ftp.ListDirectoryDetails;

    response = (

    FtpWebResponse)request.GetResponse();

     

    StreamReader reader = new StreamReader(response.GetResponseStream());

     

    String t;

    t=reader.ReadToEnd();

    Mittwoch, 10. März 2010 15:18

Alle Antworten

  • The server you are connecting to probably uses a variant of the /bin/ls format (which is unfortunately quite popular).
    The original /bin/ls represents the date of files as:

    MMM dd HH:mm  if the file was modified in the last six months
    MMM dd yyyy     otherwise.

    Given the output you posted, it seems that the server is using a variant with a threshold of 1 month instead of 6.

    The situation is uncomfortable, but it's relatively easy to solve: try to match one of the two formats with a regex and - if that fails - drop back to the other. If you end up with the time, you can always get the corresponding year (in your case, it's the year of last February, i.e. 2010; had you found a Dec with a time, you would have had to find the year of last December, i.e. 2009).

    HTH
    --mc

    Mittwoch, 10. März 2010 16:19
  • Thanks for the reply but that doesn't fix my situation.  Right now if I get the year, I don't get the timestamp at all.  There's nothing to fall back to.  I need to always have the Month, Date, Time, and Year.

    I end up doing a subsequent call to GetDateTimeStamp which gets REALLY slow when doing this against lots of files. 

    Sounds like ListDirectoryDetails is broken and needs to be fixed.  Any idea if that's something that may happen in the near future ? 
    Mittwoch, 10. März 2010 22:03
  • It's not the fault of ListDirectoryDetails: what it does is simply to send a LIST command to the FTP server and gives you back the response, exactly as it was received.

    If the information you want is not provided by the FTP server in response to LIST, there is no other way to get it except iterating through each file. Unless you have control of the FTP server, that is.

    HTH
    --mc

    Mittwoch, 10. März 2010 22:28
  • Sorry, thanks again for your response but I'm not buying it.  According to your logic then a lot of FTP clients wouldn't work or would be VERY slow, including Microsoft's own command line FTP client.  Which btw returns the information from the FTP server I'm connecting to just fine and very fast.  How about putting that code in .Net ?

    What I'm saying is "There is a way to do this obviously".  The FTP class library should abstract this and do it's job.  ListDirectoryDetails should work on more than just Microsoft's FTP server and not work on most of the others.

    I guess I'll just have to program it in sockets and do it myself, or pay someone for their FTP implemenation in C#.  What .Net provides is not useable for my situation. 
    Donnerstag, 11. März 2010 13:14
  • Good luck

    --mc
    Donnerstag, 11. März 2010 15:25
  • Rebex seems to have a fully working FTP library. 

    I know the FTP LIST format isn't standard but ListDirectoryDetails should atleast return ALL of the information.  I don't care how I have to parse it, I just need to recieve it first.

    When I worked at Microsoft I used to make sure the development teams new about shortcomings.  I hope you have some input to them.  If 3rd parties can make it work in C# then Microsoft should atleast get their code to work too.
    Donnerstag, 11. März 2010 17:31
  • As I mentioned, ListDirectoryDetails is just a wrapper for the LIST command. What you get is nothing more, nothing less, the server response.
    You don't have to take my word for this: enable tracing for System.Net by using a configuration like this

    <?xml version="1.0" encoding="utf-8"?> 
    <configuration>
    	<system.diagnostics>
    		<trace autoflush="true" />
    		<sources>
    			<source name="System.Net">
    				<listeners>
    					<add name="System.Net"/>
    				</listeners>
    			</source>
    			<source name="System.Net.HttpListener"> 
    				<listeners>
    					<add name="System.Net"/>
    				</listeners>
    			</source>
    			<source name="System.Net.Sockets">
    				<listeners>
    					<add name="System.Net"/>
    				</listeners>
    			</source>
    			<source name="System.Net.Cache">
    				<listeners>
    					<add name="System.Net"/>
    				</listeners>
    			</source>
    		</sources> 
    	<sharedListeners>
    		<add
    		name="System.Net"
    		type="System.Diagnostics.TextWriterTraceListener"
    		initializeData="C:\\Tracing\\Tracing.log" traceOutputOptions = "DateTime" />
    	</sharedListeners>
    	<switches>
    		<add name="System.Net" value="Verbose" />
    		<add name="System.Net.Sockets" value="Verbose" />
    		<add name="System.Net.Cache" value="Verbose" />
    		<add name="System.Net.HttpListener" value="Verbose" />
    	</switches>
    	</system.diagnostics>
    


    launch your FtpWebRequest and then see what the server responded in C:\Tracing\Tracing.log (you can obviously change path and filename as you see fit).

    HTH
    --mc
    • Als Antwort vorgeschlagen Levi Domingos Donnerstag, 29. Juli 2010 13:26
    Donnerstag, 11. März 2010 19:08
  • As I mentioned, ListDirectoryDetails is just a wrapper for the LIST command. What you get is nothing more, nothing less, the mp4 server response.
    You don't have to take my word for this: enable tracing for System.Net by using a configuration like this

    <?xml version="1.0" encoding="utf-8"?><configuration><system.diagnostics><trace autoflush="true" /><sources><source name="System.Net"><listeners><add name="System.Net"/></listeners></source><source name="System.Net.HttpListener"><listeners><add name="System.Net"/></listeners></source><source name="System.Net.Sockets"><listeners><add name="System.Net"/></listeners></source><source name="System.Net.Cache"><listeners><add name="System.Net"/></listeners></source></sources><sharedListeners><addname="System.Net"type="System.Diagnostics.TextWriterTraceListener"initializeData="C:\\Tracing\\Tracing.log" traceOutputOptions = "DateTime" /></sharedListeners><switches><add name="System.Net" value="Verbose" /><add name="System.Net.Sockets" value="Verbose" /><add name="System.Net.Cache" value="Verbose" /><add name="System.Net.HttpListener" value="Verbose" /></switches></system.diagnostics>


    launch your FtpWebRequest and then see what the server responded in C:\Tracing\Tracing.log (you can obviously change path and filename as you see fit).

    HTH
    --mc

    Thanks for the configuration. Now it works for me. Thanks a lot.
    Donnerstag, 22. Juli 2010 00:52
  • To deal with the variety of FTP file formats, you can use the Ultimate FTP component which handles such job nicely.
    Mittwoch, 23. Februar 2011 21:09
  • I solved it this way...

    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("<path to file>"));

    request.Method = WebRequestMethods.Ftp.GetDateTimestamp;

    request.Credentials = new NetworkCredential("<Username>", "<Password>");

    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

    string temp = response.StatusDescription;

    temp = temp.Substring(temp.LastIndexOf(" ") + 1);

    string FileCreationDateTime=temp.Substring(0, 4) + "-" + temp.Substring(4, 2) + "-" + temp.Substring(6, 2);

    Console.WriteLine(FileCreationDateTime); // THIS WILL PRINT FILE CREATION DATETIME IN yyyy-MM-dd FORMAT

    Now if you want to download this file, you need to create another request say request2

    FtpWebRequest request2 = (FtpWebRequest)WebRequest.Create(new Uri("<path to file>"));

    request2.Method = WebRequestMethods.Ftp.DownloadFile;

    request2.Credentials = new NetworkCredential("<Username>", "<Password>");

    Stream responseStream = response2.GetResponseStream();

    StreamReader reader = new StreamReader(responseStream);

    Console.WriteLine(reader.ReadToEnd());

     

    Cheers :)

    Donnerstag, 24. Februar 2011 10:17
  • Just to throw in a curve ball,

    This works fine for files but throws an exception if the object is a directory (or folder if you prefer). 

    List() System.Net.WebException - The remote server returned an error: (550) File unavailable (e.g., file not found, no access).

    Does anyone know how to get round that one?

    Dienstag, 3. April 2012 13:55
  • Skip running this code if you see a "d" in the beginning of "drwxr-xr-x" sequence, indicating this is a directory.

    Note that certain *NIX based FTP server return complete listing of folder content, so you may also need to be prepared for all the possible types returned by "ls" command when implementing generic FTP client.

    The file mode printed under the -l option consists of the entry type, owner permissions, and group permissions. The entry type character describes the type of file, as follows:
    
     b Block special file.
     c Character special file.
     d Directory.
     l Symbolic link.
     s Socket link.
     p FIFO.
     - Regular file.

    • Bearbeitet cheong00 Donnerstag, 5. April 2012 04:13
    Donnerstag, 5. April 2012 04:12