[英]Java - Can't write object as file to directory
I have a weird problem with my program. 我的程序有一个奇怪的问题。 I wrote a small program to write an object to a file in a specific directory.
我编写了一个小程序,将对象写入特定目录中的文件。
Player-Class: 玩家等级:
package readwrite;
import java.io.Serializable;
public class Player implements Serializable {
private String name;
private int level;
public Player(String name, int level) {
this.name = name;
this.level = level;
}
public String getName() {
return name;
}
public int getLevel() {
return level;
}
public void setName(String name) {
this.name = name;
}
public void setLevel(int level) {
this.level = level;
}
public String toString() {
return "Name: " + name + ", Level: " + level;
}
public void printInfo() {
System.out.println(this.toString());
}
}
PlayerReaderWriter-Class: PlayerReaderWriter-Class:
package readwrite;
import java.io.*;
public class PlayerReaderWriter {
public static Player readPlayer(String path) {
Player p = null;
try {
FileInputStream fileIn = new FileInputStream(path);
ObjectInputStream in = new ObjectInputStream(fileIn);
p = (Player) in.readObject();
in.close();
fileIn.close();
} catch(IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return p;
}
public static void writePlayer(String path, Player p) {
try {
File file = new File(path);
if (file.exists()) {
file.delete();
file.createNewFile();
} else {
file.mkdirs();
file.createNewFile();
}
FileOutputStream fileOut = new FileOutputStream(path);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(p);
out.close();
fileOut.close();
} catch(IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Player p = new Player("Foo", 64);
p.printInfo();
writePlayer("players/Player.ser", p);
Player q = readPlayer("players/Player.ser");
q.printInfo();
}
}
The problem is: When I run my program for the first time, when the directory "players" doesn't exist, I get the following error: 问题是:第一次运行程序时, 目录 “ players”不存在时,出现以下错误:
D:\Projects>java readwrite/PlayerReaderWriter
Name: Foo, Level: 64
java.io.FileNotFoundException: players\Player.ser (Access is denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at readwrite.PlayerReaderWriter.writePlayer(PlayerReaderWriter.java:34)
at readwrite.PlayerReaderWriter.main(PlayerReaderWriter.java:47)
java.io.FileNotFoundException: players\Player.ser (Access is deniedt)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at readwrite.PlayerReaderWriter.readPlayer(PlayerReaderWriter.java:11)
at readwrite.PlayerReaderWriter.main(PlayerReaderWriter.java:49)
Exception in thread "main" java.lang.NullPointerException
at readwrite.PlayerReaderWriter.main(PlayerReaderWriter.java:50)
Now the directory "players" has been created by the program and for some reason it also created a subdirectory named "Player.ser". 现在,该程序已创建目录“ players”,并且由于某种原因,它还创建了一个名为“ Player.ser”的子目录 。
When I run it a second time, it works and creates a "Player.ser" file within the "players" directory. 当我第二次运行它时,它可以工作并在“ players”目录中创建一个“ Player.ser” 文件 。
When I run it with just a empty directory named "players" it also won't work. 当我仅使用一个名为“ players”的空目录运行它时,它也将不起作用。
Regards :) 问候 :)
Look at this code: 看这段代码:
if (file.exists()) {
file.delete();
file.createNewFile();
} else {
file.mkdirs();
file.createNewFile();
}
You're saying that if players/Player.ser
doesn't exist, you should create it as a directory - and then also as a file. 您是说如果
players/Player.ser
不存在,则应将其创建为目录 ,然后再创建为文件。 That's broken. 坏了
You don't need to delete the file at all if it already exists - you can just use a FileOutputStream
and let it overwrite the file, truncating it to start with, as is the default behaviour. 如果文件已经存在,则根本不需要删除-您可以使用
FileOutputStream
并覆盖文件,并从头开始将其截断,这是默认行为。
You just need to check whether the directory exists first, eg 您只需要检查目录是否首先存在,例如
File file = new File(path);
File parent = file.getParentFile();
// TODO: Handle parent existing, but not being a directory,
// or file existing, but being a directory...
if (!parent.exists()) {
parent.mkdirs();
}
try (OutputStream output = new FileOutputStream(file)) {
// ...
}
Note the try-with-resources statement so that your output stream is always closed even if an exception is thrown. 请注意try-with-resources语句,以便即使抛出异常也始终关闭输出流。
Have a look at the JavaDoc on File#mkdirs()
: 看看
File#mkdirs()
上的JavaDoc:
Creates the directory named by this abstract pathname ...
创建以此抽象路径名命名的目录...
That says that the file is assumed to represent a directory, hence Player.ser
is created as a directory. 也就是说,假定该文件代表目录,因此将
Player.ser
创建为目录。 Use file.getParentFile().mkdirs()
instead (keep in mind that depending on the path there might be no parent). 请改用
file.getParentFile().mkdirs()
(请注意,根据路径的不同,可能没有父对象)。
Since your code is creating a directory any write operation to that File
object will fail since you can't write data directly into a directory. 由于您的代码正在创建目录,因此无法对该目录下的
File
对象执行任何写操作,因为您无法将数据直接写入目录中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.