`File.delete()`和`File.renameTo()`在项目环境中无法正常工作。

huangapple go评论72阅读模式
英文:

File.delete() & File.renameTo() Not Working in Project Environment

问题

我正在尝试创建一种身份验证系统,它使用一个名为 Users.dat 的文件来存储用户数据。目前,我正在开发一种方法来通过重写 Users.dat 文件来删除用户,从中省略指定的用户。下面的代码在一个基本环境中运行,该环境包含一个包含 .java 文件和 Users.dat 文件的全面目录,它们位于相同的位置。旧的 Users.dat 文件被删除,Users.dat.tmp 被重命名为 User.dat。(在这方面没有问题,一切都按预期工作)。

public static boolean RemoveUser(String userName) {
    // TODO 从 Users.dat 中移除用户名
    try {
        File originalFile = new File("Users.dat");
        System.out.println(originalFile.getAbsolutePath());

        BufferedReader read = new BufferedReader(new FileReader("Users.dat"));

        String line = null;
        while ((line = read.readLine()) != null) {
            if (line.indexOf(userName) != -1) {
                break;
            }
        }
        String[] userInfo = line.split(", ");
        if (!userName.equals(userInfo[2])) {
            System.out.println("未找到用户名。未删除任何用户。");
            read.close();
            return false;
        }
        File tempFile = new File(originalFile.getAbsolutePath() + ".tmp");
        PrintWriter print = new PrintWriter(new FileWriter(tempFile));
        String lineToRemove = line;

        BufferedReader read2 = new BufferedReader(new FileReader("Users.dat"));
        while ((line = read2.readLine()) != null) {
            if (!line.trim().equals(lineToRemove)) {
                print.println(line);
                print.flush();
            }
        }
        print.close();
        read.close();
        read2.close();
        System.out.println(originalFile.getAbsolutePath());
        originalFile.delete(); // 此行未能正确执行
        tempFile.renameTo(originalFile); // 此行也未能正确执行

    } catch (FileNotFoundException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    return true;
}

Users.dat 文件格式:

Joe, Last, jlast, 58c536ed8facc2c2a293a18a48e3e120, true
Sam, sone, samsone, 2c2a293a18a48e3e12058c536ed8facc, false
Jane, Best, jbest, 293a18a48e3e12052058c536ed8facc2c, false
Andrew, Estes, Aestes, 63a490d69aa544fd1272a976014ad570, true
Test, User, tuser, 63a490d69aa544fd1272a976014ad570, true

我在代码开头和结尾各有两个 System.out.println(originalFile.getAbsolutePath()) 语句,以确保在整个过程中路径没有出错。

正如我所说,代码是可以工作的,但是当我尝试在项目中实现它时,它会创建 Users.dat.tmp 文件并将正确的数据写入其中,但它不会删除旧的 Users.dat 文件,也不会将 Users.dat.tmp 文件重命名以替换 Users.dat。我确定目录是正确的,因为我正在代码执行时实际上显示它。我无法找到 originalFile.delete() 和 tempFile.renameTo(originalFile) 未能正常工作的其他原因。

编辑:
使用 java.nio.file,我能够生成一个错误消息。它的内容是:

java.nio.file.FileSystemException: C:\Path\Users.dat: 由于另一个进程正在使用此文件,因此无法访问该文件。

当显示此错误消息时,我没有打开该文件,而且在我之前提到的测试环境中使用 java.nio 时也没有遇到此错误。我不确定消息所指的其他进程是什么。

编辑 2:
我尝试在其他机器上运行此代码,一个是 Mac,另一个是 Windows 笔记本电脑,在 Mac 上代码运行得很好,但在 Windows 笔记本电脑上仍然出现相同的问题。

英文:

I am trying to create an authentication system of sorts that uses a file called Users.dat to store user data. Currently, I am developing a method to remove users by rewriting the Users.dat file, omitting the user specified. The code below works in a basic environment with an all-encompassing directory containing the .java files and the Users.dat file in the same spot. The old Users.dat file is deleted and Users.dat.tmp is renamed to User.dat. (No problems here, everything works as intended).

public static boolean RemoveUser(String userName) {
// TODO remove username from Users.dat
try {
File originalFile = new File("Users.dat");
System.out.println(originalFile.getAbsolutePath());
BufferedReader read = new BufferedReader(new FileReader("Users.dat"));
String line = null;
while ((line = read.readLine()) != null) {
if (line.indexOf(userName) != -1) {
break;
}
}
String[] userInfo = line.split(", ");
if (!userName.equals(userInfo[2])) {
System.out.println("Username not found. No users removed.");
read.close();
return false;
}
File tempFile = new File(originalFile.getAbsolutePath() + ".tmp");
PrintWriter print = new PrintWriter(new FileWriter(tempFile));
String lineToRemove = line;
BufferedReader read2 = new BufferedReader(new FileReader("Users.dat"));
while ((line = read2.readLine()) != null) {
if (!line.trim().equals(lineToRemove)) {
print.println(line);
print.flush();
}
}
print.close();
read.close();
read2.close();
System.out.println(originalFile.getAbsolutePath());
originalFile.delete(); //This line is not executing correctly
tempFile.renameTo(originalFile); //Nor is this line
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return true;
}

Users.dat file format:

Joe, Last, jlast, 58c536ed8facc2c2a293a18a48e3e120, true
Sam, sone, samsone, 2c2a293a18a48e3e12058c536ed8facc, false
Jane, Best, jbest, 293a18a48e3e12052058c536ed8facc2c, false
Andrew, Estes, Aestes, 63a490d69aa544fd1272a976014ad570, true
Test, User, tuser, 63a490d69aa544fd1272a976014ad570, true

I have two System.out.println(originalFile.getAbsolutePath()) statements, one at the beginning, one at the end to make sure the path isn't getting screwed up in the process of everything somehow.

Like I said, the code works, however, when I try to implement it in my project, it creates the Users.dat.tmp and it writes the correct data to it, but it does not delete the old Users.dat file, nor does it rename the Users.dat.tmp file to replace Users.dat. I'm certain the directory is correct, as I am literally displaying it as the code executes. I can't figure out any other reason why originalFile.delete() and tempFile.renameTo(originalFile) aren't functioning properly.

EDIT:
Using java.nio.file, I was able to produce an error message. it reads:

java.nio.file.FileSystemException: C:\Path\Users.dat: The process cannot access the file because it is being used by another process.

I don't have the file open when this error message is shown, and I don't get this error using java.nio in my testing environment mentioned at the beginning. I'm not sure what other process the message is referring to.

EDIT 2:
I tried running the code on other machines, one a Mac, the other a Windows laptop, and the code functioned on the Mac just fine, but I was still seeing the same issue on the Windows laptop.

答案1

得分: 0

我之前在主函数中调用了一个早期的函数,该函数正在访问Users.dat文件,但我从未在该函数中关闭BufferredReader。

英文:

I had an earlier function that I was calling in main that was accessing Users.dat, but I never closed the BufferredReader in that function.

答案2

得分: 0

我遇到了类似的问题。我的问题是没有关闭我读写文件的所有流。感谢您的编辑#1,那真的很有帮助。
当您包装
BufferedReader read = new BufferedReader(new FileReader("Users.dat"));
难道您不需要关闭内部的读取器吗?
即使不是为了作者,也是为了那些遇到这个问题的人(比如我),希望这些建议能够有所帮助。

英文:

I had the similar issue. My problem was not closing all the streams I read and written to the file. Thanks for your Edit #1, that was helpful
When you wrap
BufferedReader read = new BufferedReader(new FileReader("Users.dat"));
don't you need to close the inner readers too?
If not for the author, but for those who stambled upon this question (like me), hope this suggestion will be useful

huangapple
  • 本文由 发表于 2020年10月20日 00:07:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/64431166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定