[C#] Usuwanie fizyczne pliku


(Ixvokter) #1

Witam. Napisałem program, która ma za zadanie fizycznie usunąć zaznaczone pliki z poziomu kontrolki ListView. Kiedy po usunięciu pliku z samej kontrolki ListView program przechodzi do usunięcia pliku fizycznie wywala taki błąd

Dodam, iż plik, który mam zamiar usunąć nie jest otwarty ani żaden program nie powinien z niego korzystać(pliki, na których pracuje to "jpg").

Do tej pory usunął tylko jeden plik, co uznałem za przypadek losowy.


(Fiołek) #2

System nie kłamie - coś otworzyło ten plik. Na ServerFault jest pokaźna lista programów, które powiedzą, co trzyma uchwyt na dany plik.

Mój typ: jeśli to JPE-gi, to prawdopodobnie generowane są miniaturki. Coś te miniaturki musi stworzyć, więc plik został otwarty.


(Frankfurterium) #3

Coś takiego zazwyczaj występuje, kiedy nie domkniesz jakichś strumieni odczytu/zapisu. Co wcześniej robisz z tymi plikami?


(Ixvokter) #4

Odczytuje z nich eXify, ogólnie pełne dane następnie przekazywana jest lista ze ścieżkami dostępu do plików, które zostają wyświetlone w formularzu.

Program usuwa ale robi to losowo…


(Fiołek) #5

Czyli @Frankfurterium ma racje - otwierasz plik, potem go nie zamykasz. “Sam się zamknie”, gdy GC wkroczy do akcji, ale to się dzieje w nieokreślonym czasie. Do tego typu rzeczy zawsze dobrze jest używać using.


(Ixvokter) #6

A w jaki sposób mam go zamknąć. Bo o ile jest opcja zamknięcia strumienia tekstowego o tyle nie widzę nigdzie opcji typu Image.Close();

Po uruchomieniu programu mogę usunąć nawet kilka zdjęć, następnie 1 czy 2 nie i potem znów mogę usuwać. Usuwanie odbywa się bardzo losowo starałem się cokolwiek wywnioskować, lecz nic nie przychodzi mi do głowy.


(Fiołek) #7

Jeśli mówisz o System.Drawing.Image, to ona implementuje IDisposable, czyli obrazek zwalniasz używając Image.Dispose.

Nawet jeśli korzystałeś z FromStream, strumień musi być otwarty przez okres życia obiektu, więc przed usunięciem pliku musisz zwolnić obrazek.


(Ixvokter) #8

Dzięki. Problem występuje nadal, lecz rzadziej.

Dodane 29.05.2013 (Śr) 12:59

Problem rozwiązany. Oto kod, który należy wprowadzić, aby całkowicie zwolnić strumień do pliku :

image.Dispose()

image = null;

GC.Collect();

(Fiołek) #9

Z używaniem GC.Collect trzeba uważać(na StackOverflow wszystko jest ładnie opisane). Lepiej ręcznie otworzyć strumień do pliku i trzymać go razem z obrazkiem i wywoływać na nim Close/Dispose, jeśli obrazek tego dobrze nie zrobi.