Java 7 无法在 Win7 上创建具有 230 个字符路径的文件

Java 7 fails to create a file on Win7 with a 230-character path

我有一些使用 commons-io FileUtils.openOutputStream(File) 方法的新代码,用于调用时不存在的文件。这是失败的 "FileNotFoundException"。我首先认为这是 commons-io 中的一个错误,但后来我意识到它只是调用 "new FileOutputStream(file, append)",如果它不存在,它也应该创建文件。

然后我在调用 FileUtils.openOutputStream(File) 之前添加了代码,如下所示:

            if (!file.exists()) {
            logger.info("Parent file exists: " + file.getParentFile().exists());
            try {
                file.createNewFile();
            }
            catch (Exception ex) {
                logger.error("Creating file failed", ex);
            }
        }

这会为父文件打印 "true",然后是 "java.io.IOException: The system cannot find the path specified"。我在谷歌上搜索了这种情况,如果有人超过 Windows 上文件路径的假定 260 个字符限制,就会遇到这种情况。我认为这可能是相关的,但我的文件路径只有 230 个字符长。

我还尝试了一个实验,试图在我的 Cygwin bash shell 中 "touch" 相同的文件路径,并且没有遇到任何问题。

更新:

所以我采纳了部分建议,尝试使用路径和文件来执行此操作,而不仅仅是 "File"。我传入的参数是一个"File",所以我对此无能为力。我添加了以下代码:

        try {
            Path    path    = Paths.get(file.getAbsolutePath()).toAbsolutePath();
            if (!Files.exists(path.getParent())) {
                Files.createDirectories(path);
            }
            file    = Files.createFile(path).toFile();
        }
        catch (Exception ex) {
            logger.error("Failed to create file");
        }

奇怪的是,这并没有给我更好的错误信息。事实上,它不会给我任何错误信息,因为它不会失败。 NIO 似乎采用了与常规 File 对象截然不同的路径来创建文件。

更新:

现在工作正常的是以下内容:

        file    = Paths.get(file.getAbsolutePath()).toAbsolutePath().toFile();
        try {
            Path    path    = file.toPath();
            if (!Files.exists(path.getParent())) {
                Files.createDirectories(path);
            }
            if (!file.exists()) {
                file    = Files.createFile(path).toFile();
            }
        }
        catch (Exception ex) {
            logger.error("Failed to create file");
        }

奇怪的是我应该能够删除第一行,这实际上是将相对路径转换为绝对路径。我的测试 运行 在此过程中创建了 50 个左右的文件。我尝试注释掉该行,然后清除我的输出树并 运行ning 测试。尝试创建第一个文件时出现以下异常:

java.nio.file.AccessDeniedException: build\gen1\org\opendaylight\yang\gen\v1\urn\opendaylight\params\xml\ns\yang\pcep\types\rev131005\vs\tlv\vs\tlv\VendorPayload.java
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)

到底是什么?

另请注意,我从未删除使用 "File.createNewFile()" 的旧代码,我只是将 "Files" 代码放在那之前,旧代码会检查“!file.exists( )",所以理论上旧代码只会在新代码以某种方式没有创建文件的情况下执行。在第一个文件上,由于 NIO 创建失败,文件仍然不存在,它通过旧的创建代码,成功了。

甚至更奇怪,我让测试用例 运行 下一个文件,但在新代码中失败了:

java.nio.file.FileAlreadyExistsException: build\gen1\org\opendaylight\yang\gen\v1\urn\opendaylight\params\xml\ns\yang\pcep\types\rev131005\vs\tlv\VsTlv.java

请注意,该块获得该异常的唯一方法是它执行了 "Files.createFile(path).toFile()" 行,而它获得该行的唯一方法是如果“!file.exists( )" 为 TRUE,这意味着该文件不存在。我的大脑开始融化。另请注意,当我坐在此断点处时,我检查了文件系统,但该文件不存在。

这是 2015 年,你说你使用 Java 7.

Don't use File。改用这个:

final Path path = Paths.get("....").toAbsolutePath();

// use Files.exists(path.getParent()) to check for the existence;
// if it doesn't exist use Files.createDirectories() on it
Files.createFile(thePath);

如果操作失败,你至少会得到一个有意义的异常告诉你失败的原因。

这是 2015 年了。放下。 File。现在.