[prev in list] [next in list] [prev in thread] [next in thread]
List: jedit-cvs
Subject: [ jEdit-commits ] SF.net SVN: jedit: [9041]
From: vanza () users ! sourceforge ! net
Date: 2007-02-28 7:19:29
Message-ID: E1HMJ61-0004Es-P9 () sc8-pr-svn4 ! sourceforge ! net
[Download RAW message or body]
Revision: 9041
http://svn.sourceforge.net/jedit/?rev=9041&view=rev
Author: vanza
Date: 2007-02-27 23:19:29 -0800 (Tue, 27 Feb 2007)
Log Message:
-----------
Windows (at least) doesn't have an atomic rename. On top of that, it doesn't allow \
renaming if the target already exists. So, if the first attempt fails, be really \
paranoid when trying to rename the file (and also lose the atomicity in the \
process)...
Modified Paths:
--------------
plugins/CommonControls/trunk/common/io/AtomicOutputStream.java
Modified: plugins/CommonControls/trunk/common/io/AtomicOutputStream.java
===================================================================
--- plugins/CommonControls/trunk/common/io/AtomicOutputStream.java 2007-02-28 \
07:17:46 UTC (rev 9040)
+++ plugins/CommonControls/trunk/common/io/AtomicOutputStream.java 2007-02-28 \
07:19:29 UTC (rev 9041) @@ -27,7 +27,11 @@
/**
* <p>An "atomic" output stream. It is "atomic" in the sense that the
* target file won't be overwritten until "close()" is called, at which
- * point a rename is done (rename is atomic).</p>
+ * point a rename is done. A point of note that for this stream to
+ * actually be atomic, "rename" needs to be atomic, such as in POSIX
+ * systems. Windows, for example, doesn't have this property, so this
+ * stream tries to do the next best thing (delete the original, then
+ * rename).</p>
*
* <p>This stream works a little bit differently than other streams, in the
* sense that it has a second close method called {@link #rollback()}. This
@@ -69,7 +73,10 @@
public AtomicOutputStream(File path)
throws IOException
{
- this.temp = File.createTempFile(path.getName(), "tmp", path.getParentFile());
+ if (path.exists() && !path.canWrite()) {
+ throw new IOException("Can't write to " + path.getAbsolutePath());
+ }
+ this.temp = File.createTempFile(path.getName(), ".tmp", path.getParentFile());
this.out = new FileOutputStream(temp);
this.target = path;
}
@@ -90,7 +97,27 @@
try {
out.close();
if (!temp.renameTo(target)) {
- throw new IOException("Can't rename temp file to " + target.getName());
+ /*
+ * Windows doesn't allow renaming to a file that already exists.
+ * So take a "slow, non-atomic" path in this case. This is
+ * pretty ugly and absolutely not atomic, but I'm trying to be
+ * really paranoid.
+ */
+ if (target.exists()) {
+ File backup = File.createTempFile(target.getName(),
+ ".backup",
+ target.getParentFile());
+ backup.delete();
+ if (!target.renameTo(backup) || !temp.renameTo(target)) {
+ if (backup.exists() && !target.exists()) {
+ backup.renameTo(target);
+ }
+ throw new IOException("Can't rename temp file to " + target.getName());
+ }
+ backup.delete();
+ } else {
+ throw new IOException("Can't rename temp file to " + target.getName());
+ }
}
} finally {
out = null;
This was sent by the SourceForge.net collaborative development platform, the world's \
largest Open Source development site.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
jEdit-CVS mailing list
jEdit-CVS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jedit-cvs
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic