Jar 文件无权写入具有扩展名的文件
Jar file does not have access to write to files with an extension
在 Windows 10 机器上,我在 Eclipse 中有一个 Java 项目。
当我 运行 使用启动器在 Eclipse 中使用 main 方法时,程序会正确写入 csv 文件。它适用于文件名是任意扩展名或没有扩展名的情况。我正在使用 class FileWriter 来写入文件。
我将项目导出为 运行 可用的 jar,当我在命令提示符中使用“java -jar” 运行 jar 时,我使用扩展名“ .csv"、".txt"、".doc"、".xls"(以及其他),我得到一个 FileNotFoundException,表示访问被拒绝。但是,当我提供一个没有扩展名或扩展名为“.foo”的文件名时,运行 将 jar 成功写出一个文件。我想得到它,以便 jar 写出一个扩展名为“csv”的文件。
java.io.FileNotFoundException: csv\report.csv (Access is denied)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:123)
at java.base/java.io.FileWriter.<init>(FileWriter.java:66)
at project.TestRunner.createCSVFile(TestRunner.java:103)
更新
在我使用 64 位版本的 Java 16(见下文)之前。
java version "16.0.2" 2021-07-20
Java(TM) SE Runtime Environment (build 16.0.2+7-67)
Java HotSpot(TM) 64-Bit Server VM (build 16.0.2+7-67, mixed mode, sharing)
当我使用 32 位版本的 Java8 时,问题消失了。
java version "1.8.0_301"
Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
Java HotSpot(TM) Client VM (build 25.301-b09, mixed mode, sharing)
这个问题最终是一个保护过度的防病毒软件。
我认为你搞错了原因。
Windows 文件扩展名(从根本上)是一种约定。正如您所指出的,Java 将愉快地读写具有任何扩展名的文件......或没有扩展名。 Java本身不关心,WindowsOS允许。
显然,当您将应用程序放入 JAR 文件时,您 看到 一些不同的行为,并且 运行 它使用 java -jar ...
。
首先,这不是 Java 做的。 Java 完全不知道文件扩展名。从 JAR 执行或从 IDE 中执行之间没有实质性区别。 (假设 JAR 制作正确。即便如此,我考虑的差异也不会有 这个 效果。)
其次,我不认为这是 Windows 在做的。据我所知,Windows本身并没有实现对文件扩展名敏感的文件访问控制。 (或者如果有,我在 MS Windows 文档中找不到它。)
还有以下可能性:
它可能是一种保护过度的杀毒软件,或者是 Windows 访问控制的本地化。 (我不知道这是否技术上可能...)
最可能的解释是您误解了错误消息。例如:
- 他们可能在谈论目录而不是文件的权限。
- 可能是因为您正在尝试覆盖您没有写入权限的现有文件。
- 您正在使用相对路径名,并且运行正在另一个“当前目录”中。
- 类似的东西。
更新 - 根据堆栈跟踪,我怀疑这是一个“当前目录”问题。
在 Windows 10 机器上,我在 Eclipse 中有一个 Java 项目。 当我 运行 使用启动器在 Eclipse 中使用 main 方法时,程序会正确写入 csv 文件。它适用于文件名是任意扩展名或没有扩展名的情况。我正在使用 class FileWriter 来写入文件。
我将项目导出为 运行 可用的 jar,当我在命令提示符中使用“java -jar” 运行 jar 时,我使用扩展名“ .csv"、".txt"、".doc"、".xls"(以及其他),我得到一个 FileNotFoundException,表示访问被拒绝。但是,当我提供一个没有扩展名或扩展名为“.foo”的文件名时,运行 将 jar 成功写出一个文件。我想得到它,以便 jar 写出一个扩展名为“csv”的文件。
java.io.FileNotFoundException: csv\report.csv (Access is denied)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:123)
at java.base/java.io.FileWriter.<init>(FileWriter.java:66)
at project.TestRunner.createCSVFile(TestRunner.java:103)
更新 在我使用 64 位版本的 Java 16(见下文)之前。
java version "16.0.2" 2021-07-20
Java(TM) SE Runtime Environment (build 16.0.2+7-67)
Java HotSpot(TM) 64-Bit Server VM (build 16.0.2+7-67, mixed mode, sharing)
当我使用 32 位版本的 Java8 时,问题消失了。
java version "1.8.0_301"
Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
Java HotSpot(TM) Client VM (build 25.301-b09, mixed mode, sharing)
这个问题最终是一个保护过度的防病毒软件。
我认为你搞错了原因。
Windows 文件扩展名(从根本上)是一种约定。正如您所指出的,Java 将愉快地读写具有任何扩展名的文件......或没有扩展名。 Java本身不关心,WindowsOS允许。
显然,当您将应用程序放入 JAR 文件时,您 看到 一些不同的行为,并且 运行 它使用 java -jar ...
。
首先,这不是 Java 做的。 Java 完全不知道文件扩展名。从 JAR 执行或从 IDE 中执行之间没有实质性区别。 (假设 JAR 制作正确。即便如此,我考虑的差异也不会有 这个 效果。)
其次,我不认为这是 Windows 在做的。据我所知,Windows本身并没有实现对文件扩展名敏感的文件访问控制。 (或者如果有,我在 MS Windows 文档中找不到它。)
还有以下可能性:
它可能是一种保护过度的杀毒软件,或者是 Windows 访问控制的本地化。 (我不知道这是否技术上可能...)
最可能的解释是您误解了错误消息。例如:
- 他们可能在谈论目录而不是文件的权限。
- 可能是因为您正在尝试覆盖您没有写入权限的现有文件。
- 您正在使用相对路径名,并且运行正在另一个“当前目录”中。
- 类似的东西。
更新 - 根据堆栈跟踪,我怀疑这是一个“当前目录”问题。