如何创建一个新文件并同时创建缺失的父目录?

120

当使用时

file.createNewFile();

我得到以下异常
java.io.IOException: Parent directory of file does not exist: /.../pkg/databases/mydb

我在想是否有一个createNewFile函数可以创建缺失的父目录?
4个回答

178

你尝试过这个吗?

file.getParentFile().mkdirs();
file.createNewFile();

我不知道有一个调用方法可以做到这一点,但这只需要两个语句就可以轻松实现。


只有在文件路径字符串中包含父目录的情况下,此方法才有效。例如,new File("file.txt").getParentFile() 返回 null,而 new File("dir/file.txt").getParentFile() 返回与 new File("dir") 相同的结果。 - Zoltán
1
确实,如果您要创建的文件不在不存在的目录中,则不需要使用mkdirs,但我的用例是我正在创建多个文件,其中有些具有父目录,而其他文件却没有。 - Zoltán
如果您的File实例本身就是一个文件夹,您可以简单地执行以下操作:folder.mkdirs(); - zr0gravity7

26

从Java7开始,您还可以使用NIO2 API:

void createFile() throws IOException {
    Path fp = Paths.get("dir1/dir2/newfile.txt");
    Files.createDirectories(fp.getParent());
    Files.createFile(fp);
}

20

如果您确定使用的路径字符串创建文件包括父目录,即使用路径的形式为<parent-dir>/<file-name>,那么Jon的答案是有效的。

如果不是这样,即使用相对路径形式<file-name>,则getParentFile()将返回null

例如:

File f = new File("dir/text.txt");
f.getParentFile().mkdirs();     // works fine because the path includes a parent directory.

File f = new File("text.txt");
f.getParentFile().mkdirs();     // throws NullPointerException because the parent file is unknown, i.e. `null`.

因此,如果您的文件路径可能包含父目录,也可能不包含父目录,您最好使用以下代码:

File f = new File(filename);
if (f.getParentFile() != null) {
  f.getParentFile().mkdirs();
}
f.createNewFile();

出于许多原因,您应始终包括路径。否则系统怎么知道您想将该文件放在哪里呢? - NikkyD
@NikkyD 对不起,我不太理解你的评论。在我的回答中,我并不是说你没有包含路径,而是传递的路径可能不包括“_parent directories_” 。回答中也有一个这样路径的例子。 - Zoltán

0

在搜索 Kotlin 解决方案时,会出现这个通用标题的问题。
因此,在 Kotlin 1.9.0 及更高版本中,Path 类上有一个新的 createParentDirectories() 方法:

Path("my/path/to/file.txt").createParentDirectories()

我需要在我的build.gradle.kts文件中import什么东西或者添加什么内容吗?我在Android Studio IDE中遇到了Unresolved reference: createParentDirectories的问题,因为我对Android+Kotlin的东西还不太熟悉,还是个新手。 - undefined
1
@hippietrail 在 Gradle 脚本中使用的 Kotlin 版本可能与您在项目“真实”代码中使用/指定的 Kotlin 版本不同。截至目前,最新版本的 Gradle(8.4)已设置为支持 Kotlin 语言版本 1.8。因此,要在构建脚本中使用 Kotlin 1.9 中引入的新功能,需要等待新的 Gradle 版本(并更新到该版本),并希望其 Kotlin 语言级别为 1.9 或更高。请参阅 https://docs.gradle.org/current/userguide/compatibility.html#kotlin - undefined
谢谢!我发现我的Android Studio中只有Gradle 8.1版本。更新到8.4版本后,createParentDirectories()在我的Kotlin中仍然不可用。实际上,我确实想在我的Gradle脚本中使用它来生成源代码文件。Android Studio显示我的Kotlin版本是223-1.9.0-release-358-AS8836.35.2231.11090377,这是否意味着它应该可以工作? - undefined
@hippietrail 如我所说,Gradle脚本(如build.gradle.ktssettings.gradle.kts)使用自己的Kotlin版本,可能与您应用程序源代码(src/main/kotlin/src/main/java/src/test/kotlin/等中的*.kt文件)使用的Kotlin版本不同。再次强调,Gradle 8.4的Kotlin语言版本为1.8.x,这意味着在构建脚本中没有createParentDirectories()函数。我们应该等待Gradle 8.5,并希望其Kotlin语言版本设置为1.9.x - undefined
1
换句话说,你可以更改用于你的应用程序src/...代码的Kotlin版本(令人困惑的是,这在你的build.gradle.kts或settings.gradle.kts或libs.versions.toml或gradle.properties中定义),但你不能更改Gradle脚本本身的Kotlin版本(据我所知)。每个Gradle版本都附带了其内嵌的Kotlin,仅用于Gradle脚本。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接