Funny, I was just working on that same section of the book tonight. You should use the dir.list() method (dir is actually an object of type File in this case) and stuff that into a String array and loop through (off the top of my head I believe it would be like this (dir is a File object pointing to a valid directory that exists):
String  dirContents = dir.list(); for(String s : dirContents) System.out.println( s );// prints each file out so you can see if renameTo // worked or not. You could do that before and after and you should see whether your rename worked or not. Of course renameTo(File) returns a boolean so you could check that way too, it's just nice too see the file contents if you're like me [ December 05, 2007: Message edited by: nico dotti ]
That is really strange. Joshua, I tried your sample code, but only by using the createNewFile() for file1(for physically creating it).
Output: true false old.txt
After running this code, I checked in the directory structure, but there is only one file: new.txt( I did not use createNewFile() on file2). So, it is actually renaming the file, but for some reason, not reflecting it in the getName(). But why then is renameTo() returning false ???
File objects are immutable. Remember, a File object is only meant to represent a file name, not the underlying filesystem entry (at least, not directly). Among other things, this means that a File object may correspond to a non-existent file, or even a syntactically invalid path.
I recommend that you basically treat File as a special type of String that you can use for filesystem operations. This may make it more intuitive to think about behaviors like the renameTo() behavior described here, since Strings are also immutable. [ December 05, 2007: Message edited by: Kelvin Lim ]
Joined: Jan 30, 2000
[Kelvin]: File objects are immutable.
Well, that's arguable. The path info is immutable, and that's the primary point to be made here, true. But the File object does also have methods that give info on the physical file, like exists(), isDirectory(), lastModified(), etc, and it has mehtods that can alter the physical file, like delete(), createNewFile(), mkdir(), etc. Thus, a File object can behave like a mutable object. Whether it is or not is a matter of semantics, I suppose. I don't think the class fits comfortable in either category unless we use a mroe precise definition of what we mean by immutable.
Joined: Oct 10, 2007
Try to use FileWriter to create the file, and then most importantly, close the file before renaming it. The renameTo() returns true in this case. A FileWriter(at the least) is required to create the file since File class itself does not have a close(). But, as Kelvin pointed out, the File object's filename is immutable, only the underlying physical file is renamed. The code I used is as follows:
Kelvin Chenhao Lim
Joined: Oct 20, 2007
Originally posted by Jim Yingst: [Kelvin]: File objects are immutable.
Well, that's arguable.
I understand your point, but Sun's API docs also explicitly describe File objects as "immutable". This suggests that the designers of the class also saw its instances as basically representing just the pathname string, rather than the corresponding filesystem entry. From this perspective, the delete(), createNewFile(), etc methods are merely utility functions that apply the pathname string as input to filesystem operations, rather than mutators of the File object itself. This would explain the rationale behind renameTo() not updating the File object, which is what I'm trying to help elucidate here.
Here is something interesting i have noticed pertaining to renameTo() method: File dir1 = new File("dir1"); dir1.mkdir(); File dir2 = new File("dir2"); dir1.renameTo(dir2); File f1= new File(dir1, "file1"); //Line 1 File f2 = new File(dir2, "file2"); //Line 2
Line 1 fails at runtime, giving an error of "cannot find path specification" where as Line 2 runs successfully!
I am guessing this has something to do with File being immutable object. But i don't understand what is happening above here, since mkdir is not invoked on dir2, but still it represents a valid directory?
Joined: Nov 25, 2007
Correction to previous post: the code should be : File dir1 = new File("dir1"); dir1.mkdir(); File dir2 = new File("dir2"); dir1.renameTo(dir2); File f1= new File(dir1, "file1"); f1.createNewFile();//Line 1 File f2 = new File(dir2, "file2"); f2.createNewFile();//Line 2
I will say just don't go by the name and think its for renaming. It is simply a 'move' command which helps in moving a file from a source path to a target path. So if this command executes successfully, file/directory will be moved to target path and file will not exist in the source path. The main thing which we should note here is that this action is platform dependent.
Sun API says..
Whether or not this method can move a file from one filesystem to another is platform-dependent. The return value should always be checked to make sure that the rename operation was successful.