Moving files

Doesn’t work. No errors. No exceptions. The method is:

public boolean renameTo(File dest)

Renames the file denoted by this abstract pathname.

Returns:
true if and only if the renaming succeeded; false otherwise

Oh god. What do I do to find out why it failed? I have checked:

  • the input source file exists, precisely as specified
  • all elements in the directory tree to the target output file exist, and have read/write permission, and - in fact - were created by the same process that is trying to do the rename to.
  • if I type “mv [name of file reported by java] [name of destination filename reported by java]” then it works exactly as expected

/me collapses in a gibbering heap, wondering why java developers aren’t allowed to use filesystems

Are you moving the files between mounts? If so, renameTo will fail and needs to fall back on a copy/delete procedure. FYI, that’s what ‘mv’ is doing.

Great thread on this here:

http://www.javalobby.org/forums/thread.jspa?threadID=16494&tstart=0

Thanks. It would have taken me a very long time to guess that as a possibility. I didn’t even realise they were separate mounts (same hard-disk, just different partitions), and had to check to discover.

Wow. I can only underline my comment about collapsing in a gibbering heap. This is insane: how can File manipulation still be so spectacularly bad?

One wonders what the heck they think we use java for - do they really think we just write “hello world” applets?

I can’t believe that I’m about to write code so that, by the time I’ve finshed, purely because of Sun’s unwavering stupidity:

  • I read an entire file into RAM from network
  • … and stream it to disk as an OS-managed “temporary file”
  • I read that entire file from disk into RAM
  • … and stream it to disk again as a file I’ve decided not to delete, and moved elsewhere for safe keeping

Utter crap. What I should really be doing is:

  • I stream a file from network to disk
  • I update the file handle to change it’s location, allowing the OS to stream the file IFF necessary

All the rest is BS.

/me tears hair out in frustration

/me bangs head against wall, despairing that programmer time was spent on **** like generics whilst we STILL don’t have “FileSystem.numBytesAvailable()” and “File.move( FIle target )” and “File.copy( File target )”.

EDIT: at least with nio the copy operation is only four lines, and “potentially” (sun’s wording) will not stream from disk into RAM the second time, but go directly disk-to-disk.

FYI for anyone who googles and finds this when looking for it, don’t bother with the javalobby article, the original’s source is poor (and there’s some random incoherent ranting from people defending the crapness of the API). What you actually want to do is:


import java.nio.channels.*;
...
      FileInputStream in = new FileInputStream( file );
      FileChannel fin = in.getChannel();
      FileOutputStream out = new FileOutputStream( targetFile );
      FileChannel fout = out.getChannel();
      
      fin.transferTo( 0, file.length(), fout);

which should be guaranteed to do what you want. Phew. Although, you are still sacrificing the performance of a rename operation if the files happened to be on the same partition. Which you can’t tell reliably, because Sun hasn’t provided that functionailty yet.

[quote]Although, you are still sacrificing the performance of a rename operation if the files happened to be on the same partition. Which you can’t tell reliably, because Sun hasn’t provided that functionailty yet.
[/quote]
Can’t you try first with renameTo(File dest), and copy the file instead if it returns false?

[quote]Thanks. It would have taken me a very long time to guess that as a possibility. I didn’t even realise they were separate mounts (same hard-disk, just different partitions), and had to check to discover.
[/quote]
You’re welcome. It’s semantics are the same as the POSIX call, so beware. :slight_smile:

[quote]Wow. I can only underline my comment about collapsing in a gibbering heap. This is insane: how can File manipulation still be so spectacularly bad?
[/quote]
Blah, I think you need to take a break. The JavaDocs clearly spell out the semantics of the call, as well as why it might fail. When one considers that it works exactly like it’s POSIX counterpart, then it’s really no surprise that it works the way it does.

In other words, you’re turning into a gibbering fool because you’re tired. Take a break. Whatever it is, it’s not more important than you being able to think straight. :slight_smile:

[quote]FYI for anyone who googles and finds this when looking for it, don’t bother with the javalobby article, the original’s source is poor (and there’s some random incoherent ranting from people defending the crapness of the API).
[/quote]
The original is just fine, as well as guaranteed on JVM’s earlier than 1.4. Your method is definitely a cool optimization though. :slight_smile:

Maybe you should play with the Rimscape code :slight_smile: The images scale up. The images scale down. It’s pretty! Other than that, maybe you get some numbers wrong and ships blow up too fast. Well then you just chuckle cause it’s funny and try better numbers :slight_smile:

Actually, yes. I’ve just been poached to be CTO of a new games company and life has been very manic recently, with JGF falling behind (and now with less than a week before I have to start a new job; it’s one of those “start tomorrow” situations). Other issues, like book-writing etc, have made it a hectic month. I was considering posting in off-topic a general apology for being somewhat unclear/off-centre/bizarre/wrong the last few weeks. Trouble is, I never know specificially which concepts are silly and which aren’t until later on.

No, sadly, mine don’t :(. /me wonders if this is a doc fix for java 5?


public boolean renameTo(File dest)

    Renames the file denoted by this abstract pathname.

    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.

    Parameters:
        dest - The new abstract pathname for the named file 
    Returns:
        true if and only if the renaming succeeded; false otherwise 
    Throws:
        SecurityException - If a security manager exists and its SecurityManager.checkWrite(java.lang.String) method denies write access to either the old or new pathnames 
        NullPointerException - If parameter dest is null

Unfortunately, I read “filesystem” to mean what I believe is a fairly standard interpretation: “local filesystem” == all drives not network shares == one filesystem. “remore filesystems” == each network share == N additional filesystems.

It could be worded much better. But…it’s certainly a bug that it throws no exception (look at the since - it’s one of the many methods that needed updating / deprecating and renaming in 1.2 and 1.3, but obviously is one of the few that got forgotten).

Sorry, yes, I should have been more clear: if you are writing server code, which is when most people encounter this issue (especially the “store files as OS-temp files, then move them to local locations when you’ve had a chance to examine / CRC check / whatever you do” pattern, which seems to be quite common, for obvious reasons) then you will be using 1.4 anyway (server without NIO == sludge).

Without 1.4, then you need lots of code to do it, and it will ALWAYS be very inefficient, streaming from disk, to RAM, to CPU, to RAM, to disk (instead of disk-to-disk). With 1.4, you haev a chance that it’s bearable.

@tom: yes, that’s a sensible thing. I’d actually already done that in my code, but it adds a few extra lines, and I was trying to provide the shortest piece of code that solves the problem :).

FYI: it works fine using the FileChannel’s. Now JGF can accept uploads :).

NB: by design HTTP doesn’t let you check/verify a file before it’s uploaded. You have to upload the entire file, then you get to interrogate it locally.

Since JGF has to accept uploads in the region of 10’s of meg, it’s not really safe just to accept everything directly into file DB, so needed to stream to temp-files (which the OS will automatically delete when it gets desperate / reboots) and then move them iff a JGF service decided that it liked them and chose to move them into the file DB.

I know this will make you wanna cry but: g0t PHP ?

In PHP, it actually takes…hm, lemme see… 1 line ;D

PHP still sucks though ;D