2013-01-04 12 views
10

Po usunięciu pliku przy użyciu klasy system.io.file:Jak sprawdzić, czy System.IO.File.Delete usunięty plik z powodzeniem

System.IO.File.Delete(openedPdfs.path); 

trzeba uruchomić jakiś kod, jeśli plik został pomyślnie usunięty . Dopóki metoda nie zwraca żadnej wartości, sprawdzam, czy plik istnieje po metodzie usuwania. Jeśli to nadal istnieje, przypuszczam, że operacja się nie udała.

Problem polega na tym, że metoda usuwania działa dobrze, ale do pliku, który ma zostać usunięty, jest kilka sekund. Funkcja Exist zwraca true, ponieważ w momencie sprawdzania plik istnieje.

Jak mogę sprawdzić na pewno, czy pomyślnie zakończono System.IO.File.Delete(openedPdfs.path);?

Kod:

FileInfo file = new FileInfo(openedPdfs.path);  
System.IO.File.Delete(openedPdfs.path); 
if (file.Exists == false) 
{ ... } 
else 
{ ... } 
+1

„Najbardziej elegancki sposób mogę myśleć jest przy użyciu [FileSystemWatcher] (http: // MSDN. microsoft.com/en-us/library/system.io.filesystemwatcher.aspx) i zasubskrybuj wydarzenie "Deleted". " http://stackoverflow.com/questions/9370012/waiting-for-system-to-delete-file –

+3

Czy martwisz się przypadkiem, gdy usuwanie się powiedzie, ale nowy plik o tej samej nazwie zostanie utworzony przed sprawdzeniem na istnienie? – HABO

+0

@ TimSchmelter FileSystemWatcher został zgłoszony do upuszczania zdarzeń pod obciążeniem. Niektórzy sugerują, że można go użyć, aby poprawić czas reakcji, ale wciąż odpytywali z mniejszą częstotliwością, aby nie przegapić wydarzeń. FSW może również zmniejszyć wydajność, szczególnie jeśli filtry są niepotrzebnie zgrubne. –

Odpowiedz

4

Delete powinien wyrzucać wyjątek, jeśli plik nie został usunięty. W związku z tym połączenie z numerem Exists jest zbędne.

Spójrz na documentation for Delete.

+2

Istnieje niewielkie opóźnienie od zakończenia pliku File.Delete do momentu, w którym plik zostanie faktycznie usunięty. – tofutim

+12

-1: Twoje pierwsze zdanie jest błędne. Delete nie rzuca, gdy plik nie istniał wcześniej (a zatem nie jest usuwany). Przyjrzyj się dokumentacji Delete: "Jeśli plik do usunięcia nie istnieje, nie jest zgłaszany wyjątek." – mkf

0

Nie wyrzuci wyjątku, jeśli plik nie istnieje. W przypadku błędu będzie rzucać wyjątek, jeśli nie mogą być usunięte, sprawdź File.Delete

+0

Dokumentacja mówi "Jeśli plik do usunięcia nie istnieje, nie jest zgłaszany wyjątek." –

+0

@MobyDisk prawda, ale miałem na myśli, że wyrzuci wyjątek w przypadku błędu. Techniczne usunięcie nieistniejącego pliku nie jest błędem. – Zbigniew

0

zawsze można użyć

System.IO.File.Exists(path) 

Chociaż zgadzam się z Danielem, jeśli Delete nie rzucać wyjątek powinien być dobry.

1

Jest to pomocnicze wobec odpowiedzi Daniela A. White'a: Widzimy, że the signature for the method to public static void Delete(string path). Więc wyraźnie, nie otrzymasz informacji zwrotnej od wywołania Usuń, chyba że wyjątek. Ale załóżmy, że masz plik, który jest zapisywany lub aktualizowany okresowo w innym procesie:

  1. Twój program pomyślnie usuwa plik.
  2. Drugi proces odtwarza go natychmiast po usunięciu.
  3. Twój program testuje istnienie pod numerem file.Exists. Jest nowy plik o tej samej nazwie, więc zwraca true. Technicznie idziesz niewłaściwą ścieżką.

Ten dokładny scenariusz może nie być prawdziwy dla problemu, który próbujesz rozwiązać, ale sprawdzenie, czy wywołanie Delete nie zwróciło wyjątku, jest znacznie bardziej niezawodne niż poleganie na aktualnej implementacji.

0

Z uwagi i sugestie powinny być w stanie korzystać z następujących czynności, aby acheive żądany Wynik

try { 
    FileInfo file = new FileInfo(openedPdfs.path);  
    System.IO.File.Delete(openedPdfs.path); 
    // if no exception is thrown then you should assume all has gone well and put 
    // your file successfully deleted code here. 
} catch /*(Specfic exceptions can be referenced here in separate catch blocks see Daniel A. White answer)*/ { 
    // If something bad happened and the file was not deleted put handling code here 
} finally { 
    // if some action needs to be taken regardless of whether the file was successfully deleted or not put 
    // that code here 
} 
12

Jak inni zwrócili uwagę, metoda File.Delete rzuci wyjątek w przypadku awarii.

Co one pominięte zwrócić uwagę jest to, że zostanie wyrzucony wyjątek w prawie wszystkich przypadkach ale nie we wszystkich przypadkach.W szczególności, metoda File.Delete będzie zgłaszać wyjątek, jeśli plik, który ma zostać usunięty, już nie istnieje. (Duh? O czym oni myśleli?)

Powinieneś sprawdzić, czy plik istnieje przed, aby go usunąć; jeśli nie istnieje, nie powinieneś nic robić. Jeśli istnieje, powinieneś wywołać File.Delete, a jeśli to zgłasza wyjątek, to znowu nie powinieneś nic robić, ponieważ plik nie został usunięty. W przeciwnym razie powinieneś wykonać rzeczy, które powiodły się po usunięciu istniejących plików.

+0

Chociaż nie jestem apologetem MS, myślę, że konstrukcja .NET unika wyrzucania wyjątków, gdy w większości przypadków dzwoniący nie dba o to, jak i kiedy plik został usunięty. Wyjątki nie są bardzo wydajnym sposobem zgłaszania niezbyt interesującego wyniku. Directory.Create stosuje ten sam wzorzec. Znowu rozwiązuje warunki wyścigu, nie zgłaszając poprzedniego istnienia katalogu. W większości przypadków nie ma to znaczenia. WinAPI obsługuje to poprzez jawne raportowanie dokładnie tego, co stało się lub nie stało, w wartości zwracanej przez liczbę całkowitą, bez rzucania kosztownego wyjątku. –

+0

@AndrewDennison i ja nie chcemy odmawiać Microsoft w każdej sytuacji, ale wyjątki w .Net są tak przerażająco i niepotrzebnie kosztowne, że powodują, że deweloperzy podejmują kiepskie decyzje projektowe w celu uniknięcia tych kosztów. Skąd mam wiedzieć, że są niepotrzebnie kosztowne? Cóż, nie mam na to dowodu, ale wrażenie, które mam po latach programowania w każdym języku, jest takie, że wyjątki w języku Java, choć kosztowne, nie są tak kosztowne jak w dotNet. –

0

Odkryłem, że jeśli używasz metody instancji FileInfo Delete(), że właściwość instancji FileInfo istnieje, nie jest aktualizowana.
Na przykład poniższy kod spowoduje zgłoszenie pliku, który nie został znaleziony, ponieważ plik został usunięty, ale drugi kod nadal jest prawdziwy.

FileInfo output_file; 
if (output_file.Exists) output_file.Delete(); 

FileStream fs; 
if (output_file.Exists) 
{ 
    fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.ReadWrite); 
} 
else 
{ 
    fs = new FileStream(fi.FullName, FileMode.CreateNew, FileAccess.ReadWrite); 
} 

Uważam, że tworzenie nowego FileInfo od starego rozwiązaniu problemu:

FileInfo output_file; 
if (output_file.Exists) 
{ 
    output_file.Delete(); 
    output_file = new FileInfo(output_file.FullName);  
} 

FileStream fs; 
if (output_file.Exists) 
{ 
    fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.ReadWrite); 
} 
else 
{ 
    fs = new FileStream(fi.FullName, FileMode.CreateNew, FileAccess.ReadWrite); 
} 
+1

Możesz użyć 'output_file.Refresh()' aby odświeżyć stan 'FileInfo'. Ponadto, w jaki sposób to odpowiada na pytanie? – BACON

Powiązane problemy