2

We have a Windows 2008 R2 web server with FTP over SSL. This app uses .NET 4.5 and when I upload files, the date/time on the file changes to the current date/time on the server. Is there a way to have the uploaded file preserve the original (last modified) date?

Here is what I have:

FtpWebRequest clsRequest = (FtpWebRequest)WebRequest.Create(FTPFilePath);
clsRequest.EnableSsl = true;
clsRequest.UsePassive = true;
clsRequest.Credentials = new NetworkCredential(swwwFTPUser, swwwFTPPassword);
clsRequest.Method = WebRequestMethods.Ftp.UploadFile;
Byte[] bFile = File.ReadAllBytes(LocalFilePath);
Stream clsStream = clsRequest.GetRequestStream();
clsStream.Write(bFile, 0, bFile.Length);
clsStream.Close();
clsStream.Dispose();
clsRequest = null;
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Dr. Aaron Dishno
  • 1,859
  • 1
  • 29
  • 24
  • i dont have an ftp server handy but what if you zip it before you send it? maybe it would rewrite the attributes on the zip file but leave the contents alone? see here: http://stackoverflow.com/questions/2960719/ftp-script-retain-timestamp-of-a-file-after-put – Muckeypuck Jan 27 '16 at 00:11

3 Answers3

2

I know that we can assign file attributes:-

//Change the file created time.
File.SetCreationTime(path, dtCreation);
//Change the file modified time.
File.SetLastWriteTime(path, dtModified);

If you can extract the original date before you save it to the server, then you can change file attributes....something like this:-

Sftp sftp = new Sftp();
sftp.Connect(...);
sftp.Login(...);

// upload the file
sftp.PutFile(localFile, remoteFile);

// assign creation and modification time attributes
SftpAttributes attributes = new SftpAttributes();
System.IO.FileInfo info = new System.IO.FileInfo(localFile);
attributes.Created = info.CreationTime;
attributes.Modified = info.LastWriteTime;

// set attributes of the uploaded file
sftp.SetAttributes(remoteFile, attributes);

I hope this points you in the right direction.

Philo
  • 1,931
  • 12
  • 39
  • 77
  • The question is about FTP, your answer is about SFTP. And you do not even mention what SFTP library your code is using. – Martin Prikryl Jan 27 '16 at 07:20
  • I think the concept is right, Put the file on the server, then try to change the modified date. But with FTP over SSL I might have to use the System.Net.Sockets TcpClient() to set the uploaded file modified date by TransmitCommand() and using MFMT or MDTM command. Like in this post: http://stackoverflow.com/questions/2321097/how-to-send-arbitrary-ftp-commands-in-c-sharp – Dr. Aaron Dishno Jan 27 '16 at 15:00
2

There's really no standard way to update timestamp of a remote file over an FTP protocol. That's probably why the FtpWebRequest does not support it.

There are two non-standard ways to update the timestamp. Either a non-standard MFMT command:

MFMT yyyymmddhhmmss path

or a non-standard use of (otherwise standard) MDTM command:

MDTM yyyymmddhhmmss path

But the FtpWebRequest does not allow you to send a custom command either.

See for example How to send arbitrary FTP commands in C#.


So you have to use a 3rd party FTP library.

For example WinSCP .NET assembly preserves a timestamp of an uploaded file by default.

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "example.com",
    UserName = "user",
    Password = "mypassword",
};

using (Session session = new Session())
{
    // Connect
    session.Open(sessionOptions);

    // Upload
    session.PutFiles(@"c:\toupload\file.txt*", "/home/user/").Check();
}

See a full example.

Note that WinSCP .NET assembly is not a native .NET assembly. It's rather a thin .NET wrapper around a console application.

(I'm the author of WinSCP)

Community
  • 1
  • 1
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Using the MFMT or MDTM command seems to be the direction I need to go. I prefer not to use third party tools on these servers, but the simplicity would be nice. If the third party tool figured it out, it has to be possible. Thanks for the info. – Dr. Aaron Dishno Jan 27 '16 at 15:03
0

This is an older question, but I will add my solution here. I used an approach similar to the solution proposed by @Martin Prikryl, using the MDTM command. His answer shows the DateTime format string as yyyymmddhhmmss which is incorrect since it does not correctly handle the month and 24 hour time format. In this answer I corrected this issue and provided a full solution using C#.

I used the FluentFTP library which handles many other aspects of working with an FTP through C# very well. To set the modified time, this library does not support it but it has an Execute method. Using the FTP command MDTM yyyyMMddHHmmss /path/to/file.txt will set the modified time of the file.

NOTE: in my instance I needed to use the universal time, which may be the case for you.

The code below shows how to connect to the FTP and set the last modified time using the Execute method and sending the MDTM command.

FtpClient client = new FtpClient("ftp-address", "username", "password");
client.Connect();

FtpReply reply = client.Execute($"MDTM {DateTime.UtcNow.ToString("yyyyMMddHHmmss")} /path/to/file.txt");
ivcubr
  • 1,988
  • 9
  • 20
  • 28