私が持っている例はMinecraftです。 LinuxでBukkitを実行している場合、/ pluginsフォルダー内の.jarファイルを削除または更新して、「reload」コマンドを実行するだけです。
Windowsでは、.jarファイルを削除または置換しようとすると、現在使用中であると文句を言うため、サーバープロセス全体を停止する必要があります。
これは私にとって素晴らしいことですが、なぜそれが起こるのですか?
Linuxはここで何が違うのですか?
承認された回答:
Linuxは、Windowsとはまったく異なる方法でファイルを削除します。まず、*unixネイティブファイルシステムでファイルを管理する方法について簡単に説明します。
ファイルは、i-node
と呼ばれるマルチレベル構造でディスクに保持されます。 。各iノードには、単一のファイルシステム上で一意の番号があります。 iノード構造は、ファイルのサイズ、ファイルに割り当てられたデータブロックなど、ファイルに関するさまざまな情報を保持しますが、この回答のために最も重要なデータ要素はlink counter
です。 。 directories
ファイルに関する記録を保持するファイルです。各レコードには、それが参照するiノード番号、ファイル名の長さ、およびファイル名自体があります。このスキームにより、「ポインタ」、つまり、異なる名前の異なる場所にある同じファイルへの「リンク」を持つことができます。 iノードのリンクカウンターは、実際にはこのiノードを参照するリンクの数を保持します。
あるプロセスがファイルを開くとどうなりますか?まず、open()
関数はファイルレコードを検索します。次に、このiノードのメモリ内iノード構造がすでに存在するかどうかを確認します。これは、一部のアプリケーションですでにこのファイルが開かれている場合に発生する可能性があります。それ以外の場合、システムは新しいメモリ内iノード構造を初期化します。次に、システムはメモリ内のiノード構造のオープンカウンタを増やし、アプリケーションにそのファイル記述子を返します。
ファイルを削除するためのLinuxライブラリの呼び出しは、unlink
と呼ばれます。 。この関数は、ディレクトリからファイルレコードを削除し、iノードのリンクカウンタをデクリメントします。システムがメモリ内のiノード構造が存在し、そのオープンカウンタがゼロでないことを検出した場合、この呼び出しは制御をアプリケーションに返します。それ以外の場合は、リンクカウンターがゼロになったかどうかを確認し、ゼロになった場合、システムはiノードとiノード自体に割り当てられたすべてのブロックを解放してアプリケーションに戻ります。
アプリケーションがファイルを閉じるとどうなりますか?関数close()
開いているカウンターをデクリメントし、その値を確認します。値がゼロ以外の場合、関数はアプリケーションに戻ります。それ以外の場合は、iノードリンクカウンターがゼロかどうかをチェックします。ゼロの場合、アプリケーションに戻る前に、ファイルとiノードのすべてのブロックを解放します。
このメカニズムにより、ファイルを開いているときにファイルを「削除」できます。同時に、ファイルを開いたアプリケーションは、ファイル内のデータに引き続きアクセスできます。したがって、あなたの例では、JREは、ディスク上に別の更新されたバージョンがある間、ファイルのバージョンを開いたままにします。
関連:ODBKファイルとそれを復元する方法は?さらに、この機能を使用すると、通常の操作を中断することなく、システム内のすべてのアプリケーションのコアライブラリであるglibc(libc)を更新できます。
Windows
20年前、DOSでのFAT以外のファイルシステムは知りませんでした。このファイルシステムには、異なる構造と管理原則があります。これらの原則では、ファイルを開いたときにファイルを削除することはできません。そのため、DOSおよび最近のWindowsは、開いているファイルに対する削除要求を拒否する必要があります。おそらくNTFSは*nixファイルシステムと同じ動作を許可しますが、Microsoftはファイル削除の習慣的な動作を維持することを決定しました。
これが答えです。短くはありませんが、今あなたはアイデアを持っています。
編集 :
Win32
のソースに関する良い読み物 混乱:https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p =38993@Jonへのクレジット