写入 .jar 之外的文件
Write to file outside .jar
我的项目结构:
project
out
file.txt
myjar.jar
Main.class
我的代码片段(没有找到 file.txt):
BufferedWriter output = new BufferedWriter(new FileWriter("file.txt", true));
output.append(player.toString());
output.close();
如何让它找到 file.txt 并将文本附加到 file.txt?
与计算机上的每个进程相关联的当前工作目录都有一个概念。当一个进程启动时,它通常有一个当前工作目录。这也适用于 JVM 进程(当您在计算机上 运行 命令 java
时启动的进程)。
您在各种 IO class 方法中指定的 relative 路径是相对于当前工作目录的。 java.io.File
的 Javadoc 是这样说的:
By default the classes in the java.io package always resolve relative
pathnames against the current user directory. This directory is named
by the system property user.dir, and is typically the directory in
which the Java virtual machine was invoked.
因此,重要的是在调用 java
时使用正确的工作目录 。相对路径(如您的 file.txt
)是那些不以前导“/”或驱动器号开头的路径。
这是一个例子:
Foo.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Foo {
public static void main(String[] args) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader("Foo.java"))) {
System.out.println(reader.readLine());
}
}
}
这个class,当运行时,会尝试找到Foo.java
本身,并输出它的第一行,即:import java.io.BufferedReader;
.
- 将其编译为
Foo.class
。
- 比如说,
Foo.class
在您的 (Linux) 计算机上存储的文件夹是 /tmp
。
- 您现在位于
/tmp
=> java Foo
的终端上。这应该按预期打印第一行。
cd $HOME
.
java -cp /tmp Foo
(这是因为你的class还在/tmp)
这失败了:
Exception in thread "main" java.io.FileNotFoundException: Foo.java (No
such file or directory) at java.io.FileInputStream.open0(Native
Method) at java.io.FileInputStream.open(FileInputStream.java:195) at
java.io.FileInputStream.(FileInputStream.java:138) at
java.io.FileInputStream.(FileInputStream.java:93) at
java.io.FileReader.(FileReader.java:58) at
Foo.main(Foo.java:10)
这是因为它试图在当前工作目录中找到 Foo.java
,即 $HOME
,而 Foo.java
本身位于其他文件夹 (/tmp
) 中。在您的情况下,BufferedReader
的情况也适用于 BufferedWriter
。
因此,您应该 运行 这个程序 来自 file.txt
所在的文件夹:
cd project/out
java -cp myjar.jar Main
一个更好的主意是始终知道要写入的文件的位置。这样,您的程序可能会绑定到特定类型计算机上的特定路径,但至少您可以 运行 从该计算机上的任何位置毫无问题地执行它。
我的项目结构:
project
out
file.txt
myjar.jar
Main.class
我的代码片段(没有找到 file.txt):
BufferedWriter output = new BufferedWriter(new FileWriter("file.txt", true));
output.append(player.toString());
output.close();
如何让它找到 file.txt 并将文本附加到 file.txt?
与计算机上的每个进程相关联的当前工作目录都有一个概念。当一个进程启动时,它通常有一个当前工作目录。这也适用于 JVM 进程(当您在计算机上 运行 命令 java
时启动的进程)。
您在各种 IO class 方法中指定的 relative 路径是相对于当前工作目录的。 java.io.File
的 Javadoc 是这样说的:
By default the classes in the java.io package always resolve relative pathnames against the current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.
因此,重要的是在调用 java
时使用正确的工作目录 。相对路径(如您的 file.txt
)是那些不以前导“/”或驱动器号开头的路径。
这是一个例子:
Foo.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Foo {
public static void main(String[] args) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader("Foo.java"))) {
System.out.println(reader.readLine());
}
}
}
这个class,当运行时,会尝试找到Foo.java
本身,并输出它的第一行,即:import java.io.BufferedReader;
.
- 将其编译为
Foo.class
。 - 比如说,
Foo.class
在您的 (Linux) 计算机上存储的文件夹是/tmp
。 - 您现在位于
/tmp
=>java Foo
的终端上。这应该按预期打印第一行。 cd $HOME
.java -cp /tmp Foo
(这是因为你的class还在/tmp)
这失败了:
Exception in thread "main" java.io.FileNotFoundException: Foo.java (No such file or directory) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.(FileInputStream.java:138) at java.io.FileInputStream.(FileInputStream.java:93) at java.io.FileReader.(FileReader.java:58) at Foo.main(Foo.java:10)
这是因为它试图在当前工作目录中找到 Foo.java
,即 $HOME
,而 Foo.java
本身位于其他文件夹 (/tmp
) 中。在您的情况下,BufferedReader
的情况也适用于 BufferedWriter
。
因此,您应该 运行 这个程序 来自 file.txt
所在的文件夹:
cd project/out
java -cp myjar.jar Main
一个更好的主意是始终知道要写入的文件的位置。这样,您的程序可能会绑定到特定类型计算机上的特定路径,但至少您可以 运行 从该计算机上的任何位置毫无问题地执行它。