Java newOutputStream(路径、新建、关闭时删除)不写入文件
我有以下代码:Java newOutputStream(路径、新建、关闭时删除)不写入文件,java,nio,Java,Nio,我有以下代码: import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Paths; import static java.nio.file.StandardOpenOption.CREATE_NEW; import static java.nio.file.StandardOpenOption.DELETE_ON_CLOSE; publ
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.DELETE_ON_CLOSE;
public class Test {
public static void main(String[] args) throws IOException {
try (OutputStream outputStream = Files.newOutputStream(Paths.get("test"), CREATE_NEW, DELETE_ON_CLOSE)) {
outputStream.write(123);
outputStream.flush();
System.out.println("done");
}
}
}
我在调用
System.out.println
时设置了一个断点,并检查了我的工作目录。没有名为test
的文件。为什么输出流不写入文件 原因是,在Linux上,即使文件处于打开状态,您也可以从目录中删除文件(此处假定有适当的权限)。在Windows下,这是不可能的
源于
//如果关闭时删除,请立即取消文件链接。规范明确指出//当
//打开后被攻击者替换。
if(flags.deleteOnClose){ 如果您将代码修改为
for (int i = 0; i < 10; i++) {
outputStream.write(123);
outputStream.flush();
System.out.println("flush...");
Thread.sleep(10_000);
}
编辑如果您只想确保在应用程序退出时删除临时文件,请查看下面的代码段
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
在你甚至不关心文件名的情况下,你可以考虑使用一个随机生成的文件。
File tempFile = File.createTempFile("foo_", ".tmp", new File("/tmp"));
编辑可以使用另一种解决方案
InputStream
DELETE\u ON\u CLOSE打开OutputStream
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
嗯…对我有用(使用
线程。睡眠而不是断点)。你运行的是什么操作系统?OSX。如果我删除DELETE\u on\u CLOSE
,它对我也有效。我想发生的是基于Unix的操作系统会立即删除该文件,因为仍然可以访问带有打开文件句柄的删除文件。这似乎违反了API。是的,确实如此-我将在Linux上尝试,看看是否可以重新访问oduce(顺便说一句,如果你提供一个完整的应用程序,包括导入,人们会更容易复制它。)我在Linux上也经历过同样的行为,@Max-DELETE_on_CLOSE
文档确实说明了“关于何时和如何删除文件的许多细节是特定于实现的,因此没有指定。”deleteOnExit
对我不起作用,因为这是一个长期运行的流程(服务)。使用deleteOnExit
可能会导致在JVM存在之前磁盘已满。@Max您能否提供有关如何使用此文件的详细信息。由于当前您仅创建一个只写
文件,以便在关闭时删除。在当前情况下,这似乎没有任何意义。是否有其他进程/任务读取该文件?请您提供一个代码片段,说明您希望如何读取该文件。当然。我正在接受一个文件作为rest服务中的上载。我最终会将该文件作为流传递给另一个服务,但我需要首先评估上载文件的内容。鉴于该文件相当大,我不想将其全部存储在内存中。对吗现在我正在删除最后
块中的文件。这很好,看起来DELETE\u ON\u CLOSE
会更合适,但显然不是。@Max看看新添加的示例。它与DELETE\u ON\u 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