Що робить Linux по-іншому, що дозволяє мені видаляти / замінювати файли там, де Windows скаржиться, що файл зараз використовується?


30

Я маю приклад - Minecraft. Під час запуску Bukkit в Linux я можу видалити або оновити .jar файли в папці / plugins і просто виконати команду 'reload'.

У Windows мені доведеться зняти весь серверний процес, оскільки він скаржиться на те, що .jar-файл використовується зараз, коли я намагаюся його видалити або замінити.

Це для мене дивовижно, але чому це відбувається? Що тут робить Linux по-різному?

Відповіді:


35

Linux видаляє файл зовсім інакше, ніж це робить Windows. По-перше, коротке пояснення того, як керуються файлами в рідній * файловій системі * unix.

Файл зберігається на диску в багаторівневій структурі під назвою i-node. Кожен i-вузол має унікальну кількість у єдиній файловій системі. Структура i-вузла зберігає різну інформацію про файл, як-от його розмір, блоки даних, виділені для файлу тощо, але заради цієї відповіді найважливішим елементом даних є a link counter. Це directoriesфайли, які зберігають записи про файли. Кожна запис має номер i-вузла, на який вона посилається, довжину імені файлу та саме ім'я файлу. Ця схема дозволяє мати "покажчики", тобто "посилання" на один і той же файл у різних місцях з різними іменами. Лічильник посилань i-вузла фактично зберігає кількість посилань, які посилаються на цей i-вузол.

Що відбувається, коли якийсь процес відкриває файл? Спочатку open()функція шукає запис файлу. Потім він перевіряє, чи існує структура i-вузла в пам'яті для цього i-вузла. Це може статися, якщо якась програма вже відкрила цей файл. В іншому випадку система ініціалізує нову структуру i-вузла в пам'яті. Потім система збільшує відкритий лічильник структури i-вузла в пам'яті і повертає до програми свій дескриптор файлів.

Викликається виклик бібліотеки Linux для видалення файлу unlink. Ця функція видаляє запис файлів із каталогу та зменшує лічильник посилань i-вузла. Якщо система виявила, що структура i-вузла в пам'яті існує, а її відкритий лічильник не дорівнює нулю, цей виклик повертає керування програмі. В іншому випадку він перевіряє, чи лічильник зв’язків став нульовим, і якщо він це робить, то система звільняє всі блоки, виділені для i-вузла та самого i-вузла, та повертається до програми.

Що трапляється, коли програма закриває файл? Функція close()зменшує відкритий лічильник і перевіряє його значення. Якщо значення не нульове, функція повертається до програми. В іншому випадку він перевіряє, чи лічильник посилань i-node дорівнює нулю. Якщо він дорівнює нулю, він звільняє всі блоки файлу та i-вузол перед поверненням у додаток.

Цей механізм дозволяє "видалити" файл під час його відкриття. У той же час програма, яка відкрила файл, все ще має доступ до даних у файлі. Отже, JRE у вашому прикладі все ще зберігає свою версію файлу відкритою, поки на диску є ще одна оновлена ​​версія.

Крім того, ця функція дозволяє оновити glibc (libc) - основну бібліотеку всіх програм - у вашій системі, не перериваючи її нормальної роботи.

Windows

20 років тому ми не знали жодної іншої файлової системи, крім FAT в DOS. Ця файлова система має іншу структуру та принципи управління. Ці принципи не дозволяють видаляти файл під час його відкриття, тому DOS і останнім часом Windows має відхиляти будь-які запити на видалення у відкритому файлі. Можливо, NTFS дозволив би виконати таку поведінку, що і файлові системи * nix, але Microsoft вирішила зберегти звичну поведінку щодо видалення файлу.

Це відповідь. Не короткий, але тепер у вас є ідея.

Редагувати : Добре читати про джерела Win32безладу: https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993 Кредити до @Jon


1
Пробували перейменувати файл плагіна під час роботи сервера: i.imgur.com/xibyF.png
MetaGuru

відкрити вікно cmd, перейти до цього каталогу та використовувати ren MonsterB.jar MonsterB.ja_- воно повинно працювати. Він працює для файлів dll та exe, безумовно.
Серж

1
ні, Windows відображає в пам'ять частини виконуваного файлу
Серж,

9
NTFS на насправді підтримують його, але C Library fopenвикликає цю команду CreateFileз FILE_SHARE_DELETEпрапором, тому він забороняє його для більшості програм , які відкривають файли.
Випадково832

2
Обов'язковий Raymond Chen посилання: blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
Джон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.