更改文件创建日期无效

29

我正在使用以下代码修改文本文件的创建日期:

using System.IO;

...
DateTime newCreate = new DateTime(year, month, day, hour, minutes, seconds);
File.SetCreationTime("changemydate.txt", newCreate);

然而这并没有起到作用。没有错误消息,但是它根本没有改变文件的日期。

我在Dropbox文件夹和一个随机文件夹中尝试了这个方法,但都没有成功。

DateTime newCreate对象似乎是正确的。

如果有人能给我指点一个思路,那就太好了......


2
这可能是驱动器格式的副作用吗?“NTFS格式的驱动器可能会缓存文件元信息,例如文件创建时间,短时间内。因此,如果要覆盖或替换现有文件,则可能需要显式设置文件的创建时间。” - Grant Thomas
谢谢Grant Thomas,但我如何明确地做到这一点?该链接将我发送到默认的File.SetCreationTime方法... - pandita
你确定你有设置文件创建时间的权限吗?如果没有,那么你会在事件日志中看到安全事件。 - Hogan
3
你是如何验证它没有起作用的?我在一个我创建的测试文件上运行了你的代码,并且在一个NTFS卷上对我来说正常工作。我通过查看Windows资源管理器中文件的属性窗口来验证更改的时间。 - Samuel Neff
我也在Windows资源管理器中检查了一下。我认为这可能是Grant所说的情况,因为当我刚看到它时(经过几个小时的睡眠后),它实际上确实改变了文件的创建日期...谢谢大家! - pandita
6个回答

44

实际上,每个文件都有三种不同的时间:

  1. 创建时间
  2. 最后访问时间
  3. 最后写入时间(在资源管理器和其他文件管理器中显示为"文件日期")

要修改这些时间,您可以使用

File.SetCreationTime(path, time);
File.SetLastWriteTime(path, time);
File.SetLastAccessTime(path, time);

看起来,如果你想更改文件日期以显示在文件管理器(例如资源管理器)中,你应该尝试类似这样的操作:

respectively.

String path = @"changemydate.txt";                
DateTime time = new DateTime(year, month, day, hour, minutes, seconds); 

if (File.Exists(path))
    File.SetLastWriteTime(path, time);

完美!这就是正确的答案!!!更改后,它将显示在Windows资源管理器中。只需记住,如果文件不存在,则必须先保存文件。 - Junior Grão

4

我在这方面遇到了一些麻烦。这是我的代码:

    FileInfo fileInfo = new FileInfo(path);

    // do stuff that adds something to the file here

    File.SetAttributes(path, fileInfo.Attributes);
    File.SetLastWriteTime(path, fileInfo.LastWriteTime);

看起来不错,是吗?但实际上却不起作用。

然而这个确实可以运行:

    FileInfo fileInfo = new FileInfo(path);

    // note: We must buffer the current file properties because fileInfo
    //       is transparent and will report the current data!
    FileAttributes attributes = fileInfo.Attributes;
    DateTime lastWriteTime = fileInfo.LastWriteTime;

    // do stuff that adds something to the file here

    File.SetAttributes(path, attributes);
    File.SetLastWriteTime(path, lastWriteTime);

然而,Visual Studio并没有帮上忙。如果你在重置时间的那一行中断,调试器将报告你想要写回的原始值。这看起来很好,让你相信你注入了正确的日期。似乎VS不知道FileInfo对象的透明度,并报告缓存的值。

FileInfo的文档说明如下:

当首次检索属性时,FileInfo会调用Refresh方法并缓存文件的信息。在后续的调用中,必须调用Refresh以获取最新的信息副本。

嗯...好像并不完全是这样。它似乎会自动刷新。


1
无论我做什么,我仍然无法在 Win 10 上让它工作。具体来说,是File.SetCreationTime - bkwdesign
2
我需要在遍历FileInfo[]数组时添加以下内容: fileInfo.IsReadOnly = false; 这使得其他答案中显示的代码能够正常工作。 - bkwdesign

2
您可以使用此代码示例。
string fileName = @"C:\MyPath\MyFile.txt"; 
if (File.Exists(fileName)) 
{       
    DateTime fileTime = DateTime.Now; 
    File.SetCreationTime(fileName, fileTime);         
}

2
我从未遇到过SetCreationTime的问题...但是我认为你可以通过getter/setter CreationTime在FileSystemInfo上设置它。也许这样会更好地处理SetCreationTime的元信息缓存问题。
例如:
static void SetCreationTime(FileSystemInfo fsi, DateTime creationTime)
{
 fsi.CreationTime = creationTime;
}

2

再次感谢大家的帮助。我现在已经让所有的工作正常运转,并想与像我一样的其他初学者分享所有的成果:

https://github.com/panditarevolution/filestamp

主要代码位于/FileStamp/program.cs
这是一个小型命令行实用程序,允许更改文件的创建日期。我将其用作初学者项目,以教授我一些关于c#和命令行界面的基础知识。它使用了可在此处获得的有用的CommandlineParser库:

http://commandline.codeplex.com/


2
在当前的Windows 10版本的Visual Studio Community Basic中,以下语句:
Dim fi As New FileInfo(someFilename)
Dim dtf As Date = CDate(someValidDateString)
fi.CreationTime = dtf
fi.CreationTimeUtc = dtf
fi.LastWriteTime = dtf
fi.LastWriteTimeUtc = dtf
fi.LastAccessTime = dtf
fi.LastAccessTimeUtc = dtf

无法处理EML文件类型(以及其他可能的类型)。创建工作正常,但其他两个不会改变。我使用此过程将我的电子邮件存档到每年一个文件夹中,并希望能够按名称或修改日期对它们进行排序(因为这些列在资源管理器中默认存在)。

我的解决方案是将文件重命名为文件+"$",更改日期,然后将文件重新命名为原始文件名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接