2

I am writing a code in JDK 7 on Unix which compares two files. If both files are same say File A and File B.

Then it should delete File B and create a hardlink to File A.

Simple way is :

  1. Compare if files are same
    a. delete File B
    b.  use Path to File B to createLink to File A

But the problem is this is not atomic. So for some reason if my Java code dies after step 1 . I have lost the file.

One Solution is to create backup file and clean it later if process executes fine.

But I am looking for more elegant solution , something in which I can do this as a atomic operation . Please help .

Thanks

amit modi
  • 1,098
  • 1
  • 11
  • 26
  • I think the best you can do is to have some cleanup code in the `finally` block. But unless your OS supports such an atomic operation (which I doubt) there is no way to to protect yourself from Java crashing. After all, any Java that was supposed to execute won't execute if it crashes. – NullUserException Nov 02 '11 at 23:30
  • 1
    I don't really see an opportunity for anything fancy or elegant here. How about simply making the file delete the very last step? That way you don't lose anything if somehow Java crashes during this process. – Nate W. Nov 02 '11 at 23:35
  • @Shakedown You can't create a hardlink named `FilaA` if the file `FileA` exists. – NullUserException Nov 02 '11 at 23:45
  • @NullUserExceptionఠ_ఠ: Oh you're right. I suppose you'd have to create it with a different name, and then your last 2 steps would be to delete the file and then rename the link....but then how do you make that operation atomic...hmm – Nate W. Nov 03 '11 at 00:07
  • @Shakedown: at least on Linux the `rename` system call is atomic, even when overwriting the target - no special magic needed. I don't know what happens on other system, though I suspect it will be pretty much the same. – thkala Nov 03 '11 at 00:24
  • @NullUserExceptionఠ_ఠ: I have to execute the same thing on several different sites . Sometime it happens that connection breaks or other random stuff ... I have just generalized every possibility by naming it as Java crashes... and we have seen such things happening in production where the clean up was not successful so was looking for a btr approach. Thanks – amit modi Nov 03 '11 at 03:51

1 Answers1

2

The safest approach that I can think of is to create the hard link with a temporary name in the destination directory and then, as the final step, rename it, thus overwriting the destination.

Your basic algorithm would be something along the lines of the following snippet:

if (FileContentComparator.same(FileA, FileB)) {
    Files.createLink(TempB, FileA);
    TempB.renameTo(FileB);
}

Renaming files within the same filesystem is usually atomic and, thus, reasonably safe. The use of a known pattern for the temporary names would allow them to be found and handled, even if the application terminates unexpectedly before performing the final rename.

At least File.renameTo() will happily overwrite the destination without any hassle - you will have to investigate the behaviour of the Java NIO classes.

thkala
  • 84,049
  • 23
  • 157
  • 201