Java 不能 file.delete() 和 file.renameTo()

Cannot file.delete() and file.renameTo() for Java

我目前正在制作一个 Jtable 来显示和更新用户数据。更新数据时,我的代码将生成一个包含新数据的 temp.txt 文件,然后将旧的 Student_Database.txt删除后 temp.txt 将重命名为 Student_Database.txt。但是,这不起作用,生成了 temp.txt,但未删除旧的 Student_Database.txt 并且 temp.txt 未重命名。我需要有关如何修复它的指导。

    String filepath = "Student_Database.txt";
    String temppath = "temp.txt";
    File oldfile = new File(filepath);
    File newfile = new File(temppath);

    assert (oldfile.exists());

    String id = "";
    String pass = "";
    String name = "";
    String email = "";
    String number = "";
    String number_intake = "";
    String number_degree = "";

    String user_id = userID_textfield.getText();
    String password = password_textfield.getText();
    String user_name = name_textfield.getText();
    String email_id = emailaddress_textfield.getText();
    String contact_number = contactnumber_textfield.getText();
    String intake_number = intakenumber_textfield.getText();
    String degree_level = degreelevel_textfield.getText();

    try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(newfile, true)));
        Scanner x = new Scanner(oldfile))
    {

        x.useDelimiter("[,\n]");


        while (x.hasNext())
        {

            id = x.next();
            pass = x.next();
            name = x.next();
            email = x.next();
            number = x.next();
            number_intake = x.next();
            number_degree = x.next();

            if (id.equals(user_id))
            {
                pw.print(user_id+ "," +password+ "," +user_name+ "," +email_id+ "," +contact_number+ "," +intake_number+ "," +degree_level+ "\n");
            }
            else
            {
                pw.print(id+ "," +pass+ "," +name+ "," +email+ "," +number+ "," +number_intake+ "," +number_degree);
            }
        }

        Files.move(newfile.toPath(), oldfile.toPath(), StandardCopyOption.REPLACE_EXISTING);

    }
    catch(IOException e)
    {
        e.printStackTrace();
    }

打印堆栈跟踪。

java.nio.file.FileSystemException: Student_Database.txt: 该进程无法访问该文件,因为它正被另一个进程使用。

at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:92)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
at java.base/sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:384)
at java.base/sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:292)
at java.base/java.nio.file.Files.move(Files.java:1424)
at GUIs.Student_Database_Menu.jButton2ActionPerformed(Student_Database_Menu.java:476)
at GUIs.Student_Database_Menu.actionPerformed(Student_Database_Menu.java:102)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6632)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
at java.desktop/java.awt.Component.processEvent(Component.java:6397)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5008)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2762)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:743)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

使用try-with-resource(自动关闭已使用的资源), 然后就可以进行移动操作了

您可以尝试使用 java.nio 包中的 类。

(还要确保你的文件路径正确并且没有其他进程打开过文件)

简化示例:

public static void main(String[] args) {
    String filepath = "Student_Database.txt";
    String temppath = "temp.txt";
    File oldfile = new File(filepath);
    File newfile = new File(temppath);

    assert (oldfile.exists());
    
    try (
       PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(newfile, true)));
       Scanner x = new Scanner(oldfile)
    ) {

        x.useDelimiter("[,\n]");

        int id = 0;
        while (x.hasNext())  {
            id = x.nextInt();
            pw.print(id + "\n");
        }

        pw.print(++id + "\n");
    
        // If you put the move here, it will fail as there 
        // are still active handles on the files.
    } catch (IOException e) {

       // add some logging 

    } // <--- this bracket is important, the move must be below.

    // At this point the try-with-resources guarantess 
    // that all previous openened handles (defined in the try-with) have been closed.

    // do move operation here
    try {
        Files.move(newfile.toPath(), oldfile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
       // add some more logging 
    }
}

我添加了一个简单的示例。 Student_Database.txt 必须存在并且最初应该为空。每次执行此操作都会在文件中添加一个带有递增 id 的新行。