Files.newInputStream 和 StandardOpenOption.CREATE 中的 NoSuchFileException

NoSuchFileException in Files.newInputStream with StandardOpenOption.CREATE

我正在尝试打开文件进行读取或创建文件(如果不存在)。 我使用此代码:

String location = "/test1/test2/test3/";
new File(location).mkdirs();
location += "fileName.properties";
Path confDir = Paths.get(location);
InputStream in = Files.newInputStream(confDir, StandardOpenOption.CREATE);
in.close();

然后我得到 java.nio.file.NoSuchFileException

考虑到我正在使用 StandardOpenOption.CREATE 选项,如果该文件不存在,则应创建该文件。

知道我为什么会收到此异常吗?

根据 JavaDocs 你应该使用 newOutputStream() 方法来代替,然后你将创建文件:

OutputStream out = Files.newOutputStream(confDir, StandardOpenOption.CREATE);
out.close();

Java文档:

// Opens a file, returning an input stream to read from the file.
static InputStream newInputStream(Path path, OpenOption... options)

// Opens or creates a file, returning an output stream that
// may be used to write bytes to the file.
static OutputStream newOutputStream(Path path, OpenOption... options)

解释是 OpenOption 常量的使用取决于您是要在写入(输出)流还是读取(输入)流中使用它。这解释了为什么 OpenOption.CREATE 只适用于 OutputStream 而不是 InputStream.

注意:我同意@EJP,您应该查看Oracle's tutorials 以正确创建文件。

我认为您打算创建一个 OutputStream(用于写入)而不是 InputStream(用于读取)

另一种创建空文件的方便方法是使用 apache-commons FileUtils 像这样

FileUtils.touch(new File("/test1/test2/test3/fileName.properties"));

您似乎希望发生两个完全不同的事情之一:

  1. 如果文件存在,则读取;或
  2. 如果文件不存在,请创建它。

这两件事是相互排斥的,但你似乎混淆了它们。如果该文件不存在而您刚刚创建了它,那么读取它就没有意义。因此,请将两件事分开:

    Path confDir = Paths.get("/test1/test2/test3");
    Files.createDirectories(confDir);
    Path confFile = confDir.resolve("filename.properties");

    if (Files.exists(confFile))
        try (InputStream in = Files.newInputStream(confFile)) {
            // Use the InputStream...
        }
    else
        Files.createFile(confFile);

另请注意,最好使用 "try-with-resources" 而不是手动关闭 InputStream。