2012-08-01 9 views
6

utknąłem z dziwnym problemem (co jest chyba mój brak wiedzy), przedstawiam kod naruszające:funkcje Usuń Usuwa nawet podczas wywoływania aplikacja jest zamknięty

try 
{ 
    f.Delete(); 
    fTemp.MoveTo(f.FullName); 
    Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName); 
} 
catch (IOException ex) 
{ 
    Console.WriteLine("ERROR: Output file has IO exception > {0}", f.FullName); 
    Environment.ExitCode = 1; 
} 

f i fTemp są obiektami Fileinfo. Więc jeśli uruchomię to z kodem, gdzie f jest plikiem wideo odtwarzanym w mediaplayer, zgłasza wyjątek. To działa dobrze i zgodnie z oczekiwaniami. Teraz, kiedy zamykam mediaplayer, kasuje plik !? Mimo że moja aplikacja jest długo zamknięta. Nawet po zamknięciu Visual Studio nadal kasuje plik, gdy zamykam mediaplayer. Tak, jakby jakiś callback był gdzieś ustawiony, aby upewnić się, że plik zostanie usunięty w pewnym momencie. Ten kurs niechcianego zachowania. Ale nie mogę dowiedzieć się, co dokładnie idzie źle ...

Wynik teraz:

if (!IsFileLocked(f)) 
{ 
    try 
    { 
     f.Delete(); 
     fTemp.MoveTo(f.FullName); 
     Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName); 
    } 
    catch (IOException ex) 
    { 
     Console.WriteLine("ERROR: Output file has IO exception > {0}", f.FullName); 
     Environment.ExitCode = 1; 

    } 

    catch (UnauthorizedAccessException ex) 
    { 
     Environment.ExitCode = 2; 
     Console.WriteLine("ERROR: Output file is locked > {0}", f.FullName); 

    } 
} 
else 
{ 
    Environment.ExitCode = 3; 
    Console.WriteLine("ERROR: Couldn't delete file was locked"); 

} 

wiem jeszcze można zrobić lepiej między Delete i MoveTo, ale wezmę moje zmiany na teraz , kodowanie shotgun .....

+5

Odtwarzacz multimedialny najprawdopodobniej otworzył plik za pomocą opcji FILE_SHARE_DELETE, co oznacza "pozwól innym usunąć plik, gdy go używam". Plik jest oznaczony do usunięcia, a usuwanie kończy się, gdy odtwarzacz multimedialny zamknie plik. –

+2

Co to jest wiadomość podana przy użyciu wyjątku IOException? –

+0

Ale wtedy oczekiwałbym, że wyjątek nie zostanie podniesiony. Plus otworzyłem go za pomocą Windows Media Player, który w mojej książce niesłychanie blokuje pliki ... czy to nie to samo co oznaczona flaga. – JHN

Odpowiedz

3

Otrzymujesz IOException, ponieważ plik nie może zostać natychmiast usunięty lub zapisany. Jednak po wywołaniu Delete() wydaje się, że plik jest wywoływany do usunięcia.

Mimo że odtwarzacz multimedialny zatrzymuje usuwanie pliku, gdy jest otwarty, plik jest nadal oznaczony do usunięcia po jego zamknięciu, niezależnie od tego, czy program jest uruchomiony. Tak więc, gdy odtwarzacz multimedialny zamknie plik zostanie usunięty.

Możesz sprawdzić, czy plik jest w użyciu z następującego kodu, zaczerpnięte z here. Upewnij się, że nie jest zablokowany i powinieneś być dobry.

try 
{ 
    if(!IsFileLocked(f)) 
    { 
     f.Delete(); 
     fTemp.MoveTo(f.FullName); 
     Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName); 
    } 
} 

protected virtual bool IsFileLocked(FileInfo file) 
{ 
    FileStream stream = null; 

    try 
    { 
    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    } 
    catch (IOException) 
    { 
    //the file is unavailable because it is: 
    //still being written to 
    //or being processed by another thread 
    //or does not exist (has already been processed) 
    return true; 
    } 
    finally 
    { 
    if (stream != null) 
     stream.Close(); 
    } 

    //file is not locked 
    return false; 
} 
+0

Czy mogę "wyczyścić flagę" lub jakikolwiek machanizm był na miejscu. Albo jeszcze lepiej, czy istnieje możliwość sprawdzenia, czy plik może zostać usunięty, to zachowanie jest dla mnie nieprzewidywalne. – JHN

+0

Zobacz moją edycję powyżej. –

+0

Rozumiem, napisanie mojej odpowiedzi zajęło mi zbyt dużo czasu :) :) – Hinek

1

Z Windows SDK:

Funkcja DeleteFile wyznacza plik do usunięcia na blisko. Dlatego usunięcie pliku nie nastąpi, dopóki ostatni uchwyt pliku nie zostanie zamknięty. Kolejne wywołania CreateFile do otwarcia pliku kończą się niepowodzeniem z ERROR_ACCESS_DENIED.

0

O ile rozumiem, program ma czekać, aż plik zostanie usunięty, a następnie usunąć i przenieść inny plik.

W tym celu można sprawdzić, czy w pliku jest otwarty uchwyt, ale wymaga to niezarządzanego kodu. Innym sposobem byłoby użyć methode z odpowiedzi na to pytanie: Is there a way to check if a file is in use?

protected virtual bool IsFileLocked(FileInfo file) 
{ 
    FileStream stream = null; 

    try 
    { 
     stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    } 
    catch (IOException) 
    { 
     //the file is unavailable because it is: 
     //still being written to 
     //or being processed by another thread 
     //or does not exist (has already been processed) 
     return true; 
    } 
    finally 
    { 
     if (stream != null) 
      stream.Close(); 
    } 

    //file is not locked 
    return false; 
} 

Przed rozpoczęciem usunąć plik można

A) pętla aż plik może zostać usunięty

while(IsFileLocked(f)) { Thread.Sleep(100); } 

lub B) anulować

if (IsFileLocked(f)) { return; } 

Jeśli zdecydujesz A lub B zależy na twoich wymaganiach.

+0

Dwa słowa: "Stan wyścigu" – asawyer

Powiązane problemy