Linuxでは、ファイルが開いていてもディレクトリからファイルを削除できます(ここでは、適切な許可はここでは想定していません)。 Windowsでは不可能です。
sun.nio.fs.UnixChannelFactory
//クローズ時に削除した場合は、すぐにファイルのリンクを解除するソースから。仕様は明らかです
//
//が開かれた後に攻撃者に置き換えられたときに、実装が正しいファイルのリンクを解除することを保証できません。
場合(flags.deleteOnClose){ ...
あなたは、ファイルが開いていることを確認することができますが、すでに
# assumed that the code write to Paths.get("/tmp/test")
lsof | grep "/tmp/test"
... /tmp/test (deleted)
を削除
for (int i = 0; i < 10; i++) {
outputStream.write(123);
outputStream.flush();
System.out.println("flush...");
Thread.sleep(10_000);
}
としてあなたのコードを修正した場合
アプリケーションが終了したときに一時ファイルが確実に削除されるようにするには、sn以下のippet。
import java.io.File;
import java.io.OutputStream;
import java.nio.file.Files;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
public class Main {
public static void main(String[] args) throws Exception {
File file = new File("/tmp/test");
file.deleteOnExit();
System.out.println("tempFile = " + tempFile);
try (OutputStream outputStream = Files.newOutputStream(file.toPath(),
CREATE_NEW)) {
outputStream.write(123);
outputStream.flush();
System.out.println("done");
}
System.out.printf("%s exists: %s%n", file, file.exists());
}
}
ファイル/tmp/test
は、アプリケーションが終了した時点で削除されます。あなたは今、あなたもあなたが考えるかもしれないファイル名を気にしない場合は、コンソール
$ ls /tmp/test
ls: cannot access '/tmp/test': No such file or directory
にチェックすると
出力
/tmp/test exists: true
(ファイルはまだこの時点で存在しています)ランダムに生成されたものを使用する。
File tempFile = File.createTempFile("foo_", ".tmp", new File("/tmp"));
編集別の解決策は、可能性があります。
- が、それはあなたが期待するように働くだろう
InputStream
- が
OutputStream
そのためにそれをやってDELETE_ON_CLOSE
とを開く開く(ランダム一時ファイル名を使用することを好む)ファイルを作成します。
以下で動作するスニペットを見つけます。
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.DELETE_ON_CLOSE;
import static java.nio.file.StandardOpenOption.READ;
public class DeleteOnClose {
public static void main(String[] args) throws IOException {
Path path = Paths.get("/tmp/test");
System.out.println("before create: " + Files.exists(path));
Files.createFile(path);
System.out.println("after create: " + Files.exists(path));
try (InputStream in = Files.newInputStream(path, READ);
OutputStream out = Files.newOutputStream(path, APPEND,
DELETE_ON_CLOSE)) {
out.write("Hello file!".getBytes(UTF_8));
out.flush();
for (int c = in.read(); c >= 0; c = in.read()) {
System.out.print((char) c);
}
System.out.println();
}
System.out.println("after close: " + Files.exists(path));
}
}
出力
before create: false
after create: true
Hello file!
after close: false
うーん...( 'Thread.sleep'代わりにブレークポイントを使用して)私のために動作します。どのOSを実行していますか? –
OSX。 'DELETE_ON_CLOSE'も削除すればうまく動作します。 – Max
私は、開いているファイルハンドルを持つ削除されたファイルに引き続きアクセスできるので、Unixベースのオペレーティングシステムがすぐにファイルを削除するということが起こっていると思います。しかしこれはAPIに違反しているようだ。 – Max