问题
It appears that Directory.GetFiles() in C# modifies the Last access date of a file. I've googled for hours and can't seem to find a work around for this issue. Is there anyway to keep all the MAC (Modified, Accessed, Created) attributes of a file? I'm using Directory.GetDirectories(), Directory.GetFiles(), and FileInfo.
Also, the fi.LastAccessTime is giving strange results -- the date is correct, however, the time is off by 2 minutes, or a few hours.
Time of function execution: 10/31/2008 8:35 AM
Program Shows As Last Access Time
0_PDFIndex.html - 10/31/2008 8:17:24 AM
AdvancedArithmetic.pdf - 10/31/2008 8:31:05 AM
AdvancedControlStructures.pdf - 10/30/2008 1:18:00 PM
AoAIX.pdf - 10/30/2008 1:18:00 PM
AoATOC.pdf - 10/30/2008 12:29:51 PM
AoATOC2.pdf - 10/30/2008 1:18:00 PM
Actual Last Access Time
0_PDFIndex.html - 10/31/2008 8:17 AM
AdvancedArithmetic.pdf - 10/30/2008 12:29 PM
AdvancedControlStructures.pdf - 10/30/2008 12:29 PM
AoAIX.pdf - 10/30/2008 12:29 PM
AoATOC.pdf - 10/30/2008 12:29 PM
AoATOC2.pdf - 10/30/2008 12:29 PM
Below is the method I'm using. If you require more information, please let me know.
Thanks!
public void PopulateTreeView(string directoryValue, ref TreeNode parentNode)
{
string[] directoryArray = Directory.GetDirectories(directoryValue);
string[] fileArray = Directory.GetFiles(directoryValue, "*.*", SearchOption.AllDirectories);
try
{
#region Directories
if (directoryArray.Length != 0)
{
foreach (string directory in directoryArray)
{
DirectoryInfo di = new DirectoryInfo(directory);
TreeNode dirNode = parentNode.Nodes.Add(di.Name);
FileNode fn = new FileNode();
fn.bIsDir = true;
fn.dir = di;
dirNode.Tag = fn;
PopulateTreeView(directory, ref dirNode);
Application.DoEvents();
}
}
#endregion
#region Files
if (fileArray.Length != 0)
{
foreach (string file in fileArray)
{
FileInfo fi = new FileInfo(file);
TreeNode fileNode = parentNode.Nodes.Add(fi.Name);
FileNode fn = new FileNode();
fn.bIsDir = false;
fn.file = fi;
fileNode.Tag = fn;
fileNode.ImageIndex = 1;
Console.WriteLine(fi.Name + " - " + fi.LastAccessTime);
}
}
#endregion
}
catch (UnauthorizedAccessException)
{
parentNode.Nodes.Add("Access denied");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
Application.DoEvents();
}
}
i know the differences between the attributes. What i need is for the file to remain exactly the same all attributes and meta-data, as if my program never touched the file; this includes the last access date.
回答1:
I know this is far from ideal, but u can use fsutil (provided with Windows) to disable last access time writing:
fsutil behavior set disablelastaccess 1
Presumably you'd set it back to 0 once done. You can invoke this using Process.Start from C#, but there must be a better programmatic way (calling into Windows API).
Process.Start("fsutil", "behavior set disablelastaccess 1").WaitForExit();
Do note that this is a global Windows setting and would also affect disk access from outside your app...
回答2:
Access times are different from last write times. If you use fi.LastWriteTime I think you will find that the times are the same displayed in explorer or cmd window.
Of course the last access and last write could be the same, but they are not necessarily the same.
回答3:
(Reposting this as a response rather than a comment...)
I've just run this snippet of code here, and it's left the last access time alone - I can't reproduce the problem you're seeing, so Directory.GetFiles isn't broken 100% of the time.
Filemon can check whether some other app is doing this: http://technet.microsoft.com/en-us/sysinternals/bb896642.aspx
回答4:
If you're doing forensics and you don't want the drive to be modified, why are you mounting it in a writable mode? You should be accessing it read-only to guarantee that you aren't accidentally changing something. Also, I would hope that you're not running your program in the OS of the person who's disk you're examining... you have just added the disk to a machine you control, right?
回答5:
Not sure if this is related or not, but from MSDN:
When first called, FileSystemInfo calls Refresh and returns the cached information on APIs to get attributes and so on. On subsequent calls, you must call Refresh to get the latest copy of the information.
BTW, "LastAccessTime" basically tells you the last time you "looked at" the file. In the absence of stale data, this would always be "now"... Not particularly useful, IMHO.
回答6:
Access time would show a read only marker, last write would show the file being modified.
回答7:
I haven't tried this, but Google suggests:
Disable the NTFS Last Access Time Stamp
It's a system-wide change, so be aware of that...
回答8:
If you're accessing the disk for forensic purposes then you really should be doing it with the entire hard disk write-protected at the hardware level (and hence this isn't really a programming question).
A Google search for hdd "write protect"
will reveal plenty of potential solutions.
来源:https://stackoverflow.com/questions/253437/directory-getfiles-keeping-the-last-access-time