How can I rename a directory in java . I have a directory structure like /workspace/project-name/project/user/wbench/test/<multiple folders & git objects>
In the above structure I want to change test to dev (for example).
I thought Files.renameTo() will do the trick for me but this code is not working.
public ResponseMessage updateDirectoryName(String oldDirectoryName, String newDirectoryName, String userName) {
File projectDirectoryForUser = gitUtils.getProjectDirectoryFromRepoName(userName, oldDirectoryName);
try {
if (projectDirectoryForUser.exists()) {
File newDir = new File(projectDirectoryForUser.getParent() File.separator newDirectoryName);
Boolean flag =projectDirectoryForUser.renameTo(newDir);
if(flag){
System.out.println("File renamed successfully");
}else{
System.out.println("Rename operation failed");
}
}
else {
log.info("No folder found for Project in file path");
}
}
catch (Exception e){
log.info("something is not right" e.getMessage());
}
My flag is always false and name of directory is not changed. I am certainly doing something wrong not sure what?
CodePudding user response:
On Windows a common cause of failure to rename directory names is when you have
open file handles to a file inside the directory. If there is a current file handle Files.move(dir,newdir)
will report AccessDeniedException
and File.renameTo
will return false for same paths.
So: Check you have closed all editors, file explorers, CMD.EXE / consoles / terminals / xterm / bash accessing the directory to move or one of its sub-directories and files.
Here is transcript of a test I made with my build directory moving "build" <=> "build.moved" with both calls. I get similar results for Windows and Linux with these commands:
jshell> Files.move(Path.of("build"),Path.of("build.moved"))
==> build.moved
jshell> new File("build.moved").renameTo(new File("build"));
==> true
jshell> new FileInputStream("build/AL.js")
$10 ==> java.io.FileInputStream@5d6f64b1
jshell> new File("build").renameTo(new File("build.moved"))
==> false
jshell> Files.move(Path.of("build"),Path.of("build.moved"))
| Exception java.nio.file.AccessDeniedException: build -> build.moved
| at WindowsException.translateToIOException (WindowsException.java:89)
| at WindowsException.rethrowAsIOException (WindowsException.java:103)
| at WindowsFileCopy.move (WindowsFileCopy.java:403)
| at WindowsFileSystemProvider.move (WindowsFileSystemProvider.java:293)
| at Files.move (Files.java:1432)
| at (#12:1)
After closing the file, all is OK again:
jshell> $10.close()
jshell> Files.move(Path.of("build"),Path.of("build.moved"))
$15 ==> build.moved
jshell> new File("build.moved").renameTo(new File("build"))
$16 ==> true
As @VGR suggests, you get better error handling if you use Files.move
and Path
in place of File
. If you use File, avoid String concatenation and File.separator
by using the alternate constructor:
File newDir = new File(projectDirectoryForUser.getParent(), newDirectoryName);
CodePudding user response:
I think getParent()
must be getParentFile()
so you have the full path.
The newer generalisation of File
, the class Path
, together with the utilities class Files
one should better use. Files.move
is the equivalent of a File.renameTo
and might not in every case work for non-empty directories.
public ResponseMessage updateDirectoryName(String oldDirectoryName,
String newDirectoryName, String userName) {
Path projectDirectoryForUser = gitUtils.getProjectDirectoryFromRepoName(userName,
oldDirectoryName).toPath();
try {
if (Files.exists(projectDirectoryForUser)) {
Path newDir = projectDirectoryForUser.resolveSibling(newDirectoryName);
Files.move(projectDirectoryForUser, newDir);
boolean flag = Files.exist(newDir);
if (flag) {
System.out.println("File renamed successfully");
} else {
System.out.println("Rename operation failed");
}
} else {
log.info("No folder found for Project in file path");
}
} catch (Exception e){
log.info("something is not right" e.getMessage());
}
}
Whereas File
is a disk file, Path
can also be from an URI, or a packed "file" in a zip file. Different file system views. This allows File
to copy file or java resource into a zip, or rename a file in a zip.
So for the same reason one uses List
instead of an implementing ArrayList
, one better use Path
. Also I read that the Files
operations are a bit better than those of File
.
CodePudding user response:
You can't change a value os a final variable. Remove the "final" keyword from "projectDirectoryForUser" and try again.