Почему файл доступен после удаления в unix?

Я думал о проблеме параллелизма (в Solaris), что произойдет, если во время чтения кто-то попытается удалить тот же файл. У меня есть вопрос относительно существования файла в Solaris / Linux. Предположим, у меня есть файл test.txt, я открыл его в редакторе vi, а затем я открыл дубликат сеанса и удалил этот файл, но даже после удаления этого файла я могу прочитать этот файл. так вот мои вопросы:

  • Нужно ли думать о каком-либо механизме блокировки при чтении, чтобы никто не смог удалить тот же файл при чтении.

  • В чем причина показа отличного поведения от окон (как в окнах, если файл открыт в каком-то редакторе, чем мы не можем удалить этот файл)

  • После удаления этого файла, как я все еще могу прочитать этот файл, если я не закрыл файл из редактора vi.

Я спрашиваю файлы в целом, но да, для конкретной платформы, т.е. Unix. Что произойдет, если я использую Java-программу (программу чтения буфера) для чтения файла, и файл будет удален во время чтения, по-прежнему ли программа чтения буфера может прочитать файл для следующего фрагмента или нет?

2 ответа

Решение

У вас есть в основном 2 или 3 несвязанных вопроса. Текстовые редакторы любят читать весь файл в память в начале сеанса редактирования. Представьте, что каждый набранный вами символ немедленно сохраняется на диск, и все символы после него в файле переписываются на одно место дальше, чтобы освободить место. Это было бы ужасно. Намного лучше то, что вы на самом деле редактируете, это представление файла в памяти (массив указателей на строки, возможно, с некоторыми прикрепленными метаданными), которое преобразуется обратно в линейный поток только при явном сохранении.

Любая относительно свежая версия vim уведомит вас, если файл, который вы редактируете, будет удален из исходного местоположения с сообщением

E211: File "filename" no longer available

Это предупреждение не только для Unix. gvim в Windows выдаст его вам, если вы удалите редактируемый файл. Он служит напоминанием о том, что перед выходом необходимо сохранить версию, над которой вы работаете, если вы не хотите, чтобы файл исчез.

(Примечание: предупреждение не появляется мгновенно - vim проверяет существование исходного файла только тогда, когда вы возвращаете его на передний план после того, как от него отказались.)

Так что это вопрос 1, поведение текстовых редакторов - у них нет причин держать файл открытым для всего сеанса, потому что они фактически не используют его, кроме как при запуске и во время операции сохранения.

Вопрос 2, почему некоторые редакторы Windows держат файл открытым и заблокированным - я не знаю, люди из Windows чокнутые.

Вопрос 3, тот, который на самом деле о Unix, почему открытые файлы остаются доступными после их удаления - это самый интересный. Ответ, гарантированный, чтобы шокировать вас, когда представлен непосредственно:

Нет команды, функции, системного вызова или любого другого метода, который фактически запрашивает удаление файла.

лежащий в основе rm и любая другая команда, которая может появиться, чтобы удалить файл, есть системный вызов unlink, И это называется unlinkне remove или же deletefile или что-нибудь подобное, потому что это не удаляет файл. Он удаляет ссылку (также известную как запись каталога), которая представляет собой связь между файлом и именем в каталоге. (Примечание: добавлен ANSI C remove как более универсальная функция для удовлетворения не-Unix людей, которые не собирались реализовывать семантику файловой системы Unix, но в Unix, remove это просто rmdir если целью является каталог, и unlink для всего остального.)

Файл может иметь несколько ссылок (см. ln команда о том, как они создаются), что означает, что один и тот же файл известен под несколькими именами. если ты rm один из них, остальные остаются без дела и файл не удаляется. Что происходит при удалении последней ссылки? Ну, теперь у вас есть файл без имени. Но имена - это только один вид ссылки на файл. Есть как минимум 2 других: файловые дескрипторы и области mmap. Когда последняя ссылка на файл исчезает, тогда файл удаляется.

Поскольку ссылки представлены в нескольких формах, существует много видов событий, которые могут привести к удалению файла. Вот некоторые примеры:

  • отсоединить (т. д. и т. д.)
  • закрыть дескриптор файла
    • dup2 (может неявно закрывать файловый дескриптор перед заменой его копией другого файлового дескриптора)
    • exec (может привести к закрытию дескрипторов файлов с помощью флага close-on-exec)
  • munmap (не отображать область памяти)
    • mmap (если вы создаете новую карту памяти по адресу, который уже сопоставлен, старое отображение не отображается)
  • смерть процесса (которая закрывает все файловые дескрипторы и отображает все отображения памяти процесса)
    • нормальный выход
    • фатальный сигнал, генерируемый ядром (^C, segfault)
    • фатальный сигнал от другого процесса (kill)

Я не буду называть это полным списком. И я никому не рекомендую пытаться составить полный список. Просто знай, что rm это "удалить имя", а не "удалить файл", и файлы исчезают, как только они не используются.

Если вы хотите немедленно уничтожить содержимое файла, обрежьте его. Все процессы, уже использующие его, обнаружат, что его размер внезапно стал равным 0. (Это разрушение, если рассматривать обычные методы доступа к файлам. Уничтожить его более тщательно, чтобы даже тот, у кого есть доступ к сырому диску, не мог прочитать то, что раньше быть там, вам нужно перезаписать его. Есть инструмент под названием shred для этого.)

Я думаю, что ваш вопрос не имеет ничего общего с разницей между Windows/Linux. Это о том, как работает VI.

при использовании VI для редактирования файла. VI создаст файл.swp. И файл.swp - это то, что вы на самом деле редактируете. В то же время, если другие пользователи удалят исходный файл, это не повлияет на ваше редактирование. И когда вы набираете: w в VI, VI будет использовать файл.swp для перезаписи исходного файла.

Другие вопросы по тегам