5

次の動作を理解しようとしています。私の古いコード、

String path = "C:/temp/sample.txt";
String mode= "rw";
FileChannel channel = new RandomAccessFile(path, mode).getChannel();
// some code to write to this file

// finally delete
File file = new File(path);
boolean isDeleted = file.delete();
System.out.println("Is Deleted - " + isDeleted);

O/P - 削除済み - false

「channel.close();」を実行した場合のみ ファイルを削除する前に。ファイルを削除して true を返しますか。

新しい置き換えコード、

String path = "C:/temp/sample.txt";
FileChannel fChannel = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
// some code to write to this file

// finally delete
File file = new File(path);
boolean isDeleted = file.delete();
System.out.println("Is Deleted - " + isDeleted);

O/P - 削除済み - true

ただし、これはアプリケーションが終了するまでファイルを削除しません。「fChannel.close()」を使用すると、すぐに削除されます。

いくつかの質問、

  1. なぜ異なる動作なのか、RA と Seekable Channel など、両方が異なるタイプであることを理解しています。しかし、よくわかりませんが、なぜ delete が異なる動作をする必要があるのでしょうか。
  2. 新しい実装では、アプリケーションが終了するまでファイルを削除しない場合は、false を返す (つまり、close が呼び出されるまで削除しない) か、すぐに削除する必要があります。

バグに遭遇したのか、何かが欠けているのかわかりません。任意のポインターが役立ちます。

ありがとう

4

1 に答える 1

1

の仕様からRandomAccessFile.getChannel():

返されるチャネルの位置は、getFilePointer メソッドによって返されるこのオブジェクトのファイル ポインタ オフセットと常に等しくなります。このオブジェクトのファイル ポインター オフセットを変更すると、明示的に、またはバイトの読み取りまたは書き込みによって、チャネルの位置が変更され、その逆も同様です。このオブジェクトを介してファイルの長さを変更すると、ファイル チャネルを介して表示される長さが変更され、その逆も同様です。

つまり、返されたチャネルと はRandomAccessFile双方向の関係を維持し、どちらも開いているか閉じています。したがって、この点で、をロックしたままにしているのは ではFileChannelなくRandomAccessFile、チャネルが開いている間も開いているです。File

closeそのようなを呼び出すとFileChannel、関連付けられているものも閉じられRandomAccessFile、操作を妨げるものは JRE 内に残りませんdelete

対照的に、FileChannelビアを作成する場合FileChannel.open、関連付けられたFileInputStreamFileOutputStream、および操作RandomAccessFileを妨げませんFile.delete

そのため、JVM/JRE 内にdelete操作を妨げるものが何もない場合、下にあるオペレーティング システムの動作が表示されMicrosoft Windowsます。

DeleteFile 関数

既存のファイルを削除します。

…</p>

DeleteFile関数は、ファイルを閉じるときに削除するようにマークします。したがって、ファイルの最後のハンドルが閉じられるまで、ファイルの削除は行われません。ファイルを開くためのCreateFileへの後続の呼び出しは、 ERROR_ACCESS_DENIEDで失敗します。

これはまさに観察された動作です。JVM を終了する必要はありませんFileChannel。削除を完了するには、JVM を閉じるだけで十分です。

于 2014-12-03T13:15:15.973 に答える