Skip to content

Dlaczego nie mogę zmieniać używanych plików w systemie Windows tak, jak mogę w systemach Linux i OS X?

6 de lipiec de 2021
sshot5148b8822daab

Kiedy używasz Linuksa i OS X, system operacyjny nie powstrzyma Cię przed usunięciem pliku, który jest aktualnie używany w systemie Windows, nie będziesz mógł tego zrobić. Co daje? Dlaczego można edytować i usuwać używane pliki w systemach wywodzących się z systemu Unix, ale nie w systemie Windows?

Dzisiejsza sesja pytań i odpowiedzi przychodzi do nas dzięki uprzejmości SuperUser — pododdziału Stack Exchange, społecznościowej grupy witryn internetowych z pytaniami i odpowiedziami.

Pytanie

Czytnik SuperUser the.midget chce wiedzieć, dlaczego Linux i Windows inaczej traktują używane pliki:

Jedną z rzeczy, która zastanawiała mnie, odkąd zacząłem używać Linuksa, jest fakt, że pozwala on zmienić nazwę pliku, a nawet go usunąć podczas czytania. Przykładem jest to, jak przypadkowo próbowałem usunąć film podczas jego odtwarzania. Udało mi się i byłem zaskoczony, gdy dowiedziałem się, że w pliku można zmienić prawie wszystko, nie przejmując się, czy jest on aktualnie używany, czy nie.

Więc co dzieje się za kulisami i uniemożliwia mu bezmyślne usuwanie rzeczy w Windowsie, tak jak w Linuksie?

Odpowiedź

Współtwórcy SuperUser rzucili trochę światła na sytuację dla the.midget. Zdumiony pisze:


Za każdym razem, gdy otwierasz lub wykonujesz plik w systemie Windows, system Windows blokuje plik w miejscu (jest to uproszczenie, ale zwykle jest to prawda). Pliku zablokowanego przez proces nie można usunąć, dopóki ten proces go nie zwolni. Dlatego za każdym razem, gdy system Windows musi się zaktualizować, musisz ponownie uruchomić komputer, aby zaczął działać.

Z drugiej strony, uniksopodobne systemy operacyjne, takie jak Linux i Mac OS X, nie blokują pliku, ale raczej podstawowe sektory dysku. Może się to wydawać trywialne zróżnicowanie, ale oznacza to, że wpis pliku w spisie treści systemu plików można usunąć bez zakłócania pracy żadnego programu, który już ma otwarty plik. Możesz więc usunąć plik, gdy jest on nadal wykonywany lub w inny sposób używany, i będzie on nadal istniał na dysku, dopóki jakiś proces ma do niego otwarty uchwyt, nawet jeśli jego wpis w tabeli plików zniknął.

David Schwartz rozwija ten pomysł i podkreśla, jak powinno wyglądać idealnie i jak wygląda w praktyce:

Windows domyślnie stosuje automatyczne, obowiązkowe blokowanie plików. UNIXy domyślnie stosują ręczne, kooperatywne blokowanie plików. W obu przypadkach wartości domyślne można nadpisać, ale w obu przypadkach zwykle nie są.

Wiele starego kodu Windows używa API C/C++ (funkcje takie jak fopen) zamiast natywnego API (funkcje takie jak CreateFile). Interfejs API C/C++ nie daje możliwości określenia, jak będzie działać obowiązkowe blokowanie, więc otrzymujesz wartości domyślne. Domyślny „tryb udostępniania” zwykle uniemożliwia operacje „konfliktowe”. Jeśli otworzysz plik do zapisu, zakłada się, że zapisy są w konflikcie, nawet jeśli nigdy nie zapisujesz do tego pliku. To samo dotyczy zmian nazw.

I tutaj jest gorzej. Poza otwieraniem do odczytu lub zapisu, interfejs API C/C++ nie zapewnia możliwości określenia, co zamierzasz zrobić z plikiem. API musi więc zakładać, że wykonasz jakąkolwiek legalną operację. Ponieważ blokowanie jest obowiązkowe, otwarcie, które pozwala na operację powodującą konflikt, zostanie odrzucone, nawet jeśli kod nigdy nie zamierzał wykonać operacji powodującej konflikt, ale tylko otwierał plik w innym celu.

Więc jeśli kod używa interfejsu API C/C++ lub używa natywnego interfejsu API bez szczególnego zastanowienia się nad tymi problemami, zakończy się to uniemożliwiając maksymalny zestaw możliwych operacji dla każdego otwieranego pliku i nie będzie w stanie otworzyć pliku, chyba że każda możliwa operacja, którą może działać na nim po otwarciu, jest bezkonfliktowy.

Moim zdaniem metoda Windows działałaby znacznie lepiej niż metoda UNIX, gdyby każdy program wybrał swoje tryby udostępniania i tryby otwierania mądrze i rozsądnie obsługiwane przypadki awarii. Jednak metoda UNIX działa lepiej, jeśli kod nie zawraca sobie głowy myśleniem o tych kwestiach. Niestety, podstawowe API C/C++ nie jest dobrze odwzorowane na API plików Windows w sposób, który obsługuje tryby udostępniania i dobrze otwiera się konflikty. Tak więc wynik netto jest trochę bałaganiarski.

Masz to: dwa różne podejścia do obsługi plików dają dwa różne wyniki.

Masz coś do dodania do wyjaśnienia? Dźwięk w komentarzach. Chcesz przeczytać więcej odpowiedzi od innych doświadczonych technologicznie użytkowników Stack Exchange? Sprawdzić pełny wątek dyskusji tutaj.

Czy ten post był pomocny?