Dlaczego nie mogę zmienić plików w użyciu w systemie Windows, tak jak ja w systemach Linux i OS X?
Kiedy korzystasz z systemu Linux i OS X, system operacyjny nie powstrzyma cię przed usunięciem aktualnie używanego pliku w systemie Windows, co spowoduje, że nie będziesz mógł tego zrobić. Co daje? Dlaczego można edytować i usuwać pliki w użyciu w systemach pochodnych Unix, ale nie w systemie Windows?
Dzisiejsza sesja pytań i odpowiedzi przychodzi do nas dzięki uprzejmości SuperUser - poddziału Stack Exchange, opartego na społecznościach grupowania witryn z pytaniami i odpowiedziami.
Pytanie
Czytnik SuperUser the.midget chce wiedzieć, dlaczego Linux i Windows traktują pliki w użyciu w różny sposób:
Jedną z rzeczy, która mnie zaintrygowała, odkąd zacząłem używać Linuksa, jest fakt, że pozwala on zmienić nazwę pliku, a nawet usunąć go podczas odczytu. Przykładem jest sposób, w jaki przypadkowo próbowałam usunąć wideo podczas odtwarzania. Udało mi się i byłem zaskoczony, gdy dowiedziałem się, że możesz zmienić prawie wszystko w pliku, nie dbając o to, czy jest on aktualnie używany, czy nie..
Więc to, co dzieje się za kulisami i nie pozwala mu bezmyślnie usuwać rzeczy w systemie Windows, tak jak to tylko możliwe w Linuksie?
Odpowiedź
Dostawcy SuperUser rzucają nieco światła na sytuację z the.midget. Zdziwiony pisze:
Za każdym razem, gdy otwierasz lub uruchamiasz plik w systemie Windows, system Windows blokuje plik w miejscu (jest to uproszczenie, ale zazwyczaj jest prawdziwe). Plik zablokowany przez proces nie może zostać usunięty, dopóki ten proces go nie zwolni. Właśnie dlatego, gdy system Windows musi sam się aktualizować, konieczne jest ponowne uruchomienie systemu.
Z drugiej strony, podobne do Unix systemy operacyjne, takie jak Linux i Mac OS X, nie blokują pliku, a raczej leżące u jego podstaw sektory dyskowe. Może to wydawać się trywialnym rozróżnieniem, ale oznacza to, że rekord pliku w spisie treści systemu plików można usunąć bez zakłócania działania żadnego programu, który już ma otwarty plik. Możesz więc usunąć plik, gdy nadal jest on wykonywany lub w inny sposób używany, i będzie istnieć na dysku, dopóki jakiś proces ma otwarty uchwyt do niego, nawet jeśli jego wpis w tabeli plików zniknął.
David Schwartz rozwija ideę i podkreśla, jak rzeczy powinny być idealnie i jak są w praktyce:
System Windows domyślnie stosuje automatyczne, obowiązkowe blokowanie plików. Domyślnie UNIXy to ręczne, wspólne blokowanie plików. W obu przypadkach wartości domyślne można przesłonić, ale w obu przypadkach zwykle nie.
Wiele starych systemów Windows wykorzystuje API C / C ++ (funkcje takie jak fopen) zamiast natywnego API (funkcje takie jak CreateFile). Interfejs API C / C ++ nie pozwala określić sposobu działania blokowania obowiązkowego, więc otrzymasz ustawienia domyślne. Domyślny "tryb udostępniania" ma tendencję do blokowania "sprzecznych" operacji. Jeśli otworzysz plik do zapisu, zakłada się, że zapisy powodują konflikt, nawet jeśli nigdy nie piszesz do pliku. Podobnie jak w przypadku nazw.
I tu jest, gdzie jest gorzej. Poza otwarciem do odczytu lub zapisu, API C / C ++ nie ma możliwości określenia, co zamierzasz zrobić z tym plikiem. A więc API musi zakładać, że zamierzasz przeprowadzić jakąkolwiek legalną operację. Ponieważ blokowanie jest obowiązkowe, odmowa otwarcia, która pozwala na konfliktową operację, zostanie odrzucona, nawet jeśli kod nigdy nie miał na celu wykonania operacji powodującej konflikt, ale tylko otwierał plik w innym celu.
Jeśli więc kod korzysta z interfejsu API C / C ++ lub używa natywnego interfejsu API, nie myśląc o tych problemach, zostaną one zamknięte, zapobiegając maksymalnemu zestawowi możliwych operacji dla każdego otwieranego pliku i niemożności otwarcia pliku, chyba że każda możliwa operacja mógł wykonać na nim po otwarciu nie jest ograniczony.
Moim zdaniem, metoda Windowsa działałaby znacznie lepiej niż metoda UNIX, gdyby każdy program wybrał tryby udostępniania i mądrze otworzył tryby, a sowicie obsłużył awarie. Metoda UNIX działa jednak lepiej, jeśli kod nie zastanawia się nad tymi problemami. Niestety, podstawowy interfejs API C / C ++ nie mapuje się dobrze na interfejs API pliku Windows w sposób, który dobrze obsługuje tryby udostępniania i sprzeczne otwarcie. Więc wynik netto jest trochę brudny.
Masz to: dwa różne podejścia do obsługi plików dają dwa różne wyniki.
Czy masz coś do dodania do wyjaśnienia? Dźwięk w komentarzach. Chcesz przeczytać więcej odpowiedzi od innych użytkowników Stack Exchange, którzy znają się na technologii? Sprawdź cały wątek dyskusji tutaj.