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
ren MonsterB.jar MonsterB.ja_
его - оно должно работать. Это работает для DLL и EXE-файлов определенно.fopen
вызываетCreateFile
сFILE_SHARE_DELETE
флагом, поэтому она запрещает его большинству программ, открывающих файлы.