Search code examples
javafiledelete-filefile-rename

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


I am currently making a Jtable that will display and update user data. When updating data, my code will generate a temp.txt file with the new data and then the old Student_Database.txt will be deleted and temp.txt will be renamed to Student_Database.txt. However, this not working, temp.txt is generated but the old Student_Database.txt is not deleted and the temp.txt is not renamed. I need guidance on how to fix it.

    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();
    }

Print Stack Trace.

java.nio.file.FileSystemException: Student_Database.txt: The process cannot access the file because it is being used by another process.

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$4.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$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.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$5.run(EventQueue.java:745)
at java.desktop/java.awt.EventQueue$5.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)

Solution

  • Use try-with-resource (that closes the used resources automatically), and afterward you can do the move operation.

    You could try using the classes from the java.nio package instead.

    (Also make sure that your file paths are correct and no other processes have opened the files)

    Simplified example:

    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 
        }
    }
    

    I've added a simple example. The Student_Database.txt must exist and should initially be empty. Every execution of this will add a new line with an incremented id to the file.