Directory.GetFiles хранит время последнего доступа
Похоже, что Directory.GetFiles() в C# изменяет дату последнего доступа к файлу. Я часами гуглял и, похоже, не могу обойти эту проблему. Есть ли способ сохранить все атрибуты MAC (измененные, доступные, созданные) файла? Я использую Directory.GetDirectories(), Directory.GetFiles() и FileInfo.
Кроме того, fi.LastAccessTime дает странные результаты - дата верна, однако время отключено на 2 минуты или несколько часов.
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
Ниже метод, который я использую. Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.
Спасибо!
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();
}
}
Я знаю разницу между атрибутами. Мне нужно, чтобы файл оставался точно таким же, все атрибуты и метаданные, как если бы моя программа никогда не касалась файла; это включает в себя дату последнего доступа.
8 ответов
Я знаю, что это далеко от идеала, но вы можете использовать fsutil (поставляется с Windows) для отключения записи в последний раз:
fsutil behavior set disablelastaccess 1
Предположительно, вы установите его обратно в 0, как только закончите. Вы можете вызвать это с помощью Process.Start из C#, но должен быть лучший программный способ (вызов в Windows API).
Process.Start("fsutil", "behavior set disablelastaccess 1").WaitForExit();
Обратите внимание, что это глобальный параметр Windows, который также влияет на доступ к диску извне вашего приложения...
(Репостить это как ответ, а не как комментарий...)
Я только что выполнил этот фрагмент кода здесь, и он оставил последнее время доступа в одиночестве - я не могу воспроизвести проблему, с которой вы столкнулись, поэтому Directory.GetFiles не ломается в 100% случаев.
Filemon может проверить, выполняет ли это какое-либо другое приложение: http://technet.microsoft.com/en-us/sysinternals/bb896642.aspx
Если вы занимаетесь экспертизой и не хотите, чтобы диск был изменен, почему вы монтируете его в режиме записи? Вы должны иметь доступ к нему только для чтения, чтобы гарантировать, что вы случайно ничего не измените. Кроме того, я надеюсь, что вы не запускаете свою программу в ОС того человека, чей диск вы проверяете... вы только что добавили диск на компьютер, которым вы управляете, верно?
Время доступа отличается от времени последней записи. Если вы используете fi.LastWriteTime, я думаю, вы обнаружите, что время одинаково отображается в проводнике или окне cmd.
Конечно, последний доступ и последняя запись могут быть одинаковыми, но они не обязательно совпадают.
Если вы обращаетесь к диску в криминалистических целях, то вам действительно следует делать это со всем жестким диском, защищенным от записи на аппаратном уровне (и, следовательно, на самом деле это не вопрос программирования).
Поиск Google для hdd "write protect"
покажет множество потенциальных решений.
Не уверен, если это связано или нет, но из MSDN:
При первом вызове FileSystemInfo вызывает Refresh и возвращает кэшированную информацию об API для получения атрибутов и т. Д. При последующих вызовах вы должны позвонить в "Обновить", чтобы получить последнюю копию информации.
Кстати, "LastAccessTime" в основном говорит вам, когда вы в последний раз "смотрели" файл. При отсутствии устаревших данных это всегда будет "сейчас"... Не особо полезно, ИМХО.
Время доступа будет показывать маркер только для чтения, последняя запись будет показывать изменяемый файл.
Я не пробовал это, но Google предлагает:
Отключить отметку времени последнего доступа NTFS
Это общесистемное изменение, так что помните об этом...