Java代码可以在我的笔记本电脑上使用,但不能在我的台式机上使用



我使用IntelliJ。我有一个管理学生成绩的班。它可以编辑文件,我正在编写一个新的.temp文件,并对其进行重命名。然后旧文件被删除。在我的笔记本电脑(mac(上,这很好,但在我的桌面(windows(上,一切都正常,但旧文件不会被删除,临时文件也不会被重命名。

以下是我编辑文件的方法:

private static void editStuGrade() throws Exception {
System.out.println("Enter a course grade you want to change (q1,q2,q3,mid,final): ");
String editInput = command.next();
System.out.println("Enter a new score: ");
String newGrade = command.next();
Path p = Paths.get(System.getProperty("user.dir"),"src","Assignment1", student.name + ".txt");
File inputFile = new File(p.toString());
FileInputStream inputStream = new FileInputStream(inputFile);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
File outputFile = new File(p + ".temp");
FileOutputStream outputStream = new FileOutputStream(outputFile);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
BufferedWriter writer = new BufferedWriter(outputStreamWriter);
if (editInput.equalsIgnoreCase("q1")) {
writer.write(student.name + "," +  student.id + "," + newGrade + "," + student.quiz2
+ "," + student.quiz3 + "," + student.midterm + "," + student.finalTest);
writer.close();
} else if (editInput.equalsIgnoreCase("q2")) {
writer.write(student.name + "," +  student.id + "," + student.quiz1 + "," + newGrade
+ "," + student.quiz3 + "," + student.midterm + "," + student.finalTest);
writer.close();
} else if (editInput.equalsIgnoreCase("q3")) {
writer.write(student.name + "," +  student.id + "," + student.quiz1 + "," + student.quiz2
+ "," + newGrade + "," + student.midterm + "," + student.finalTest);
writer.close();
} else if (editInput.equalsIgnoreCase("mid")) {
writer.write(student.name + "," +  student.id + "," + student.quiz1 + "," + student.quiz2
+ "," + student.quiz3 + "," + newGrade + "," + student.finalTest);
writer.close();
} else if (editInput.equalsIgnoreCase("final")) {
writer.write(student.name + "," +  student.id + "," + student.quiz1 + "," + student.quiz2
+ "," + student.quiz3 + "," + student.midterm + "," + newGrade);
writer.close();
}
inputFile.delete();
outputFile.renameTo(new File(p.toString()));
System.out.println("Successful.");
}

Windows是一片特殊的雪花。与其他操作系统不同(或者更确切地说,Windows文件系统与其他文件系统不同(,它不允许您删除任何打开的文件,也不允许您重命名或删除包含任何打开文件的目录。与其他根本不介意的操作系统相反;磁盘上的文件只是"指针",任何打开文件的进程都会得到一个指针。在所有指针都消失之前,该文件不会真正从磁盘中删除,因此,您可以删除文件——如果该文件仍然打开,没有问题——只要它是文件,该文件就不会消失。在这方面,它与java垃圾收集非常相似。

但窗户上却不是这样。

你的代码中有一个错误——你没有管理你的资源。这导致文件被打开,然后你试图删除它们——这在非windows文件系统上有效,但在windows上是不允许的——即使你是仍然打开文件的进程,你也不能删除文件。

必须关闭资源,并且您有责任这样做。假设代码可以通过多种方式退出(不仅是"运行到方法的末尾",还有:使用return、抛出异常、使用breakcontinue进行流控制等(。因此,试图手动编写代码以确保您的资源对所有可能的退出路径都是关闭的,这很烦人,也很容易出错,所以,不要这样做。使用java的语言功能:

永远不要打开资源,除非您在尝试使用块时这样做

看起来像这样:

try (var outputStream = new FileOutputStream(outputFile)) {
// outputStream exists here and can be interacted with as normal
}

无论代码流如何"退出"try块,资源一旦退出就会自动关闭。这很好,不仅因为这可以让你删除这些文件,还因为每个进程打开的文件数量有限,所以如果你不能关闭,任何不重要的应用程序都会因为打开的文件太多而很快崩溃。

什么是资源?javadoc将告诉您,并使用常识。大多数InputStream和OutputStream都是-任何实现AutoClosable的类型都是。如果你new X()它们,你肯定必须关闭它们。如果您调用的方法听起来像是"生成"资源(例如:socket.getInputStreamFiles.newInputStream(,则必须关闭它们。

使用try () {}执行此操作。

一旦你这样做了,你可以删除这些文件很好,即使是在窗口上。

相关内容

最新更新