Что 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-узла нулю. Если он равен нулю, он освобождает все блоки файла и 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флагом, поэтому она запрещает его большинству программ, открывающих файлы.
Random832

2
Обязательная ссылка Рэймонда Чена: blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
Джон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.