2009-09-19 10 views
18

Gdy wywołuję FileInfo(path).LastAccessTime lub FileInfo(path).LastWriteTime na pliku, który jest w trakcie zapisywania, zwraca czas utworzenia pliku, a nie ostatni czas, w którym został zapisany (tj. teraz)..NET FileInfo.LastWriteTime i FileInfo.LastAccessTime są nieprawidłowe

Czy istnieje sposób na uzyskanie tych informacji?

Edycja: Do wszystkich odpowiedzi do tej pory. Nie próbowałem Refresh(), ale to też nie działa. Zwrócono mi czas, w którym plik został zapisany. To samo dotyczy metody statycznej i tworzenia nowej instancji o wartości FileInfo.

Codymix może mieć odpowiedź, ale nie korzystam z systemu Windows Server (przy użyciu Windows 7) i nie wiem, gdzie ustawienie ma być testowane.

Edycja 2: Nikt nie jest interesujący, że ta funkcja nie działa?

+0

Zauważyłem również, że te funkcje dają niewiarygodne informacje; np. gdy plik znajduje się w udziale sieciowym (samba). Zauważyłem, że dokumenty MSDN (http://msdn.microsoft.com/en-us/library/system.io.file.getlastaccesstime(v=VS.90).aspx) mówią teraz: "Ta metoda może zwrócić niedokładną wartość. . " –

Odpowiedz

3

Czy próbowałeś zadzwonić pod numer Refresh() tuż przed uzyskaniem dostępu do usługi (aby uniknąć uzyskania wartości buforowanej)? Jeśli to nie zadziała, czy spojrzałeś na to, co Eksplorator pokazuje w tym samym czasie? Jeśli Explorer pokazuje złe informacje, to prawdopodobnie coś, czego naprawdę nie można adresować - może to być na przykład informacja, że ​​informacje są aktualizowane tylko po zamknięciu uchwytu pliku.

14

Wartości FileInfo są ładowane tylko raz, a następnie buforowane. Aby uzyskać aktualną wartość, zadzwoń Refresh() zanim się właściwość:

f.Refresh(); 
t = f.LastAccessTime; 

Innym sposobem, aby uzyskać wartość bieżąca jest za pomocą statycznych metod na klasy File:

t = File.GetLastAccessTime(path); 
+0

t = File.GetLastAccessTime (ścieżka); jest nadal nieaktualny, jeśli proces został zapisany, ale blokuje plik. Ta odpowiedź jest niepoprawna. – rolls

4

Od MSDN:

Kiedy pierwszy nazywa, FileSystemInfo wzywa Refresh i zwraca pamięci podręcznej informacje na temat API do dostać atrybuty i tak dalej. Na kolejnych połączeniach musisz wywołać funkcję Odśwież, aby uzyskać najnowszą kopię informacji.

FileSystemInfo.Refresh()

Jeśli aplikacja jest jeden robi pisanie, myślę, że będziemy mieć do „dotknąć” plik przez ustawienie właściwości LastWriteTime siebie między każdego bufora danych piszesz . Niektóre psuedokod:

while(bytesWritten < totalBytes) 
{ 
    bytesWritten += br.Write(buffer); 
    myFileInfo.LastWriteTime = DateTime.Now; 
} 

Nie jestem pewien, jak poważnie wpłynie to na wydajność zapisu.

4

Istnieje ustawienie w oknach, które czasami jest ustawione szczególnie w systemach serwerowych, dzięki czemu czasy modyfikacji plików nie są ustawione dla lepszej wydajności.

+0

codymanix ma rację, mówią o tym ustawieniu tutaj: http://blogs.technet.com/b/filecab/archive/2006/11/07/disabling-last-access-time-in-windows-vista-to- poprawić-ntfs-performance.aspx – DukeOfMarmalade

+0

Ten link wspomina tylko czas ostatniej modyfikacji. –

0

odpowiedź Tommy Carlier jest mi do myślenia ...

Dobrym sposobem na zwizualizowanie różnic jest osobne uruchomienie dwóch fragmentów kodu (po prostu użyłem LinqPAD) w sposób opisany poniżej, a także uruchomiony monitor procesu.

while(true) 
    File.GetLastAccessTime([file path here]); 

i

FileInfo bob = new FileInfo(path); 

while(true){ 
    string accessed = bob.LastAccessTime.ToString(); 
} 

Jeśli spojrzeć na monitor Process podczas uruchamiania pierwszego fragmentu widać powtarzające się i ciągłe próby dostępu do pliku dla procesu LINQPad. Drugi fragment będzie początkowy dostęp do pliku, dla którego zobaczysz działania w monitorze procesu, a następnie bardzo niewiele później.

Jeśli jednak zmienisz plik (właśnie otworzyłem plik tekstowy, który monitorowałem za pomocą FileInfo i dodałem znak i zapisałem), zobaczysz serię prób dostępu przez proces LinqPAD do pliku w monitorze procesu.

To ilustruje zachowanie bez buforowania i buforowane w dwóch różnych podejściach.

Czy metoda bez pamięci podręcznej nosi otwór w dysku?

EDIT

wyjechałem czując wszystko mądry nad moim testowania, a następnie wykorzystywane zachowanie buforowania FileInfo w moim usługi windows (w zasadzie siedzieć w pętli i powiedzieć: „Ma-file-changed-HAS- zmieniono plik ... "przed wykonaniem przetwarzania)

Chociaż to podejście działało na moim polu dev, nie działało w środowisku produkcyjnym, tj. proces właśnie działał bez względu na to, czy plik się zmienił, czy nie. Zmieniłem moje podejście do sprawdzania i użyłem GetLastAccessTime jako części tego. Nie wiem, dlaczego zachowałoby się inaczej na serwerze produkcyjnym ... ale nie jestem tym specjalnie zainteresowany.

+0

W końcu tak, tak samo jak czas i przestrzeń. – PsyKzz

2

Jak James wskazał LastAccessTime nie jest aktualizowany.

LastWriteTime również przeszedł pewien zwrot od czasów Vista. Gdy proces ma już otwarty plik, a inny proces sprawdza LastWriteTime, nie zobaczy nowego czasu zapisu przez długi czas, dopóki proces nie zamknie pliku. Jako obejście można otworzyć i zamknąć plik z procesu zewnętrznego. Po wykonaniu tej czynności możesz spróbować ponownie przeczytać LastWriteTime, która jest aktualną wartością.

Jeśli aplikacja zaimplementuje coś w rodzaju toczącego się programu rejestrującego, który zamyka plik, a następnie zmienia jego nazwę na inną, wystąpią również problemy, ponieważ czas utworzenia i rozmiar pliku "starego" są zapamiętywane przez system operacyjny mimo że utworzyłeś nowy plik. Obejmuje to błędne raporty dotyczące rozmiaru pliku, nawet jeśli odtworzono plik log.txt od zera, który nadal ma rozmiar 0 bajtów. Ta funkcja nazywa się tunelowaniem systemu plików systemu operacyjnego, który jest nadal obecny w systemie Windows 8.1. Przykład implementacji tego problemu można znaleźć w RollingFlatFileTracelistener z Enterprise Library (http://home.elka.pw.edu.pl/~mrudnik/CREAM/Logging/Src/Logging/TraceListeners/RollingFlatFileTraceListener.cs).

Możesz zobaczyć efekty tunelowania systemu plików na własnej maszynie z powłoki cmd.

echo test > file1.txt 
ren file1.txt file2.txt 
Wait one minute 
echo test > file1.txt 

dir /tc file*.txt 
... 
05.07.2015 19:26     7 file1.txt 
05.07.2015 19:26     7 file2.txt 

System plików jest automatem stanów. Utrzymywanie prawidłowej synchronizacji stanów jest trudne, jeśli zależy Ci na wydajności i poprawności. Ten dziwny zespół tunelowania jest oczywiście nadal używany przez aplikację, która robi np. automatycznie zapisz plik i przenieś go do lokalizacji zapisu, a następnie ponownie odtwórz plik w tej samej lokalizacji. W przypadku tych aplikacji ma sens nadanie plikowi nowej daty utworzenia, ponieważ została ona skopiowana tylko dookoła. Niektóre instalatory również robią takie sztuczki, aby tymczasowo przenieść pliki do innej lokalizacji i zapisują zawartość z powrotem później, aby ominąć niektóre pliki sprawdzane w poszukiwaniu niektórych haków instalacyjnych.

Powiązane problemy