fix windows file rename bug

This commit is contained in:
Manfred Karrer 2014-07-09 13:34:35 +02:00
parent d221ae3aec
commit 2778779414
7 changed files with 129 additions and 119 deletions

View file

@ -76,7 +76,7 @@ public class BitSquare extends Application
// use a local data dir as default storage dir (can be overwritten in the settings)
// TODO save root preferences always in app dir top get preferred storage location
StorageDirectory.setStorageDirectory(new File(StorageDirectory.getApplicationDirectory().getAbsolutePath() + "/data"));
StorageDirectory.setStorageDirectory(new File(StorageDirectory.getApplicationDirectory().getCanonicalPath() + "/data"));
// currently there is not SystemTray support for java fx (planned for version 3) so we use the old AWT

View file

@ -29,7 +29,7 @@ public class BitSquareWalletAppKit extends WalletAppKit
{
if (!directory.mkdir())
{
throw new IOException("Could not create named directory " + directory.getAbsolutePath());
throw new IOException("Could not create named directory " + directory.getCanonicalPath());
}
}
FileInputStream walletStream = null;

View file

@ -665,7 +665,13 @@ public class MessageFacade
private void setupStorage()
{
myPeer.getPeerBean().setStorage(new StorageDisk(StorageDirectory.getStorageDirectory().getAbsolutePath() + "/" + BitSquare.getAppName() + "_tomP2P"));
try
{
myPeer.getPeerBean().setStorage(new StorageDisk(StorageDirectory.getStorageDirectory().getCanonicalPath() + "/" + BitSquare.getAppName() + "_tomP2P"));
} catch (IOException e)
{
e.printStackTrace();
}
}
private void saveMyAddressToDHT() throws IOException

View file

@ -1,6 +1,5 @@
package io.bitsquare.storage;
import com.google.bitcoin.core.Utils;
import com.google.bitcoin.utils.Threading;
import io.bitsquare.BitSquare;
import io.bitsquare.util.FileUtil;
@ -54,7 +53,7 @@ public class Storage
lock.lock();
try
{
saveObjectToFile((Serializable) rootMap);
FileUtil.saveFile(prefix, storageFile, (Serializable) rootMap);
} finally
{
lock.unlock();
@ -120,7 +119,7 @@ public class Storage
{
lock.lock();
rootMap.put(key, value);
saveObjectToFile((Serializable) rootMap);
FileUtil.saveFile(prefix, storageFile, (Serializable) rootMap);
} finally
{
lock.unlock();
@ -217,63 +216,6 @@ public class Storage
}
}
private void saveObjectToFile(Serializable serializable)
{
try
{
final File tempFile = FileUtil.getTempFile("temp_" + prefix);
try (final FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream))
{
objectOutputStream.writeObject(serializable);
// Attempt to force the bits to hit the disk. In reality the OS or hard disk itself may still decide
// to not write through to physical media for at least a few seconds, but this is the best we can do.
fileOutputStream.flush();
fileOutputStream.getFD().sync();
if (Utils.isWindows())
{
final File canonical = storageFile.getCanonicalFile();
if (!canonical.exists())
{
if (!canonical.createNewFile())
{
throw new IOException("Failed to create new file " + canonical);
}
}
if (!tempFile.renameTo(canonical))
{
throw new IOException("Failed to rename " + tempFile + " to " + canonical);
}
}
else if (!tempFile.renameTo(storageFile))
{
throw new IOException("Failed to rename " + tempFile + " to " + storageFile);
}
} catch (IOException e)
{
e.printStackTrace();
log.error("saveObjectToFile failed." + e);
if (tempFile.exists())
{
log.warn("Temp file still exists after failed save.");
if (!tempFile.delete())
{
log.warn("Cannot delete temp file.");
}
}
}
} catch (IOException e)
{
e.printStackTrace();
log.error("getTempFile failed." + e);
}
}
private Object readObjectFromFile(File file) throws IOException, ClassNotFoundException
{

View file

@ -113,40 +113,9 @@ public class DSAKeyUtil
privKeyFileOutputStream.flush();
privKeyFileOutputStream.getFD().sync();
if (Utils.isWindows())
{
// Work around an issue on Windows whereby you can't rename over existing files.
final File pubKeyCanonicalFile = pubKeyFile.getCanonicalFile();
if (pubKeyCanonicalFile.exists() && !pubKeyCanonicalFile.delete())
{
throw new IOException("Failed to delete pubKeyCanonicalFile for replacement with save");
}
if (!pubKeyTempFile.renameTo(pubKeyCanonicalFile))
{
throw new IOException("Failed to rename " + pubKeyTempFile + " to " + pubKeyCanonicalFile);
}
final File privKeyCanonicalFile = privKeyFile.getCanonicalFile();
if (privKeyCanonicalFile.exists() && !privKeyCanonicalFile.delete())
{
throw new IOException("Failed to delete privKeyCanonicalFile for replacement with save");
}
if (!privKeyTempFile.renameTo(privKeyCanonicalFile))
{
throw new IOException("Failed to rename " + privKeyTempFile + " to " + privKeyCanonicalFile);
}
}
else
{
if (!pubKeyTempFile.renameTo(pubKeyFile))
{
throw new IOException("Failed to rename " + pubKeyTempFile + " to " + pubKeyFile);
}
if (!privKeyTempFile.renameTo(privKeyFile))
{
throw new IOException("Failed to rename " + privKeyTempFile + " to " + privKeyFile);
}
}
FileUtil.saveTempFileToFile(pubKeyTempFile, pubKeyFile);
FileUtil.saveTempFileToFile(privKeyTempFile, privKeyFile);
} finally
{
if (pubKeyTempFile.exists())
@ -170,7 +139,6 @@ public class DSAKeyUtil
}
}
private static KeyPair readKeyPairFromFiles(File pubKeyFile, File privKeyFile) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException
{
lock.lock();

View file

@ -1,8 +1,8 @@
package io.bitsquare.util;
import com.google.bitcoin.core.Utils;
import io.bitsquare.BitSquare;
import java.io.File;
import java.io.IOException;
import java.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -24,21 +24,106 @@ public class FileUtil
public static String getApplicationFileName()
{
File executionRoot = new File(StorageDirectory.class.getProtectionDomain().getCodeSource().getLocation().getFile());
log.trace("getApplicationFileName " + executionRoot.getAbsolutePath());
// check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar")
if (executionRoot.getAbsolutePath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty("os.name").startsWith("Mac"))
try
{
File appFile = executionRoot.getParentFile().getParentFile().getParentFile();
try
log.trace("getApplicationFileName " + executionRoot.getCanonicalPath());
} catch (IOException e)
{
e.printStackTrace();
}
// check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar")
try
{
if (executionRoot.getCanonicalPath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty("os.name").startsWith("Mac"))
{
int lastSlash = appFile.getCanonicalPath().lastIndexOf("/") + 1;
return appFile.getCanonicalPath().substring(lastSlash).replace(".app", "");
} catch (IOException e)
{
e.printStackTrace();
File appFile = executionRoot.getParentFile().getParentFile().getParentFile();
try
{
int lastSlash = appFile.getCanonicalPath().lastIndexOf("/") + 1;
return appFile.getCanonicalPath().substring(lastSlash).replace(".app", "");
} catch (IOException e)
{
e.printStackTrace();
}
}
} catch (IOException e)
{
e.printStackTrace();
}
return BitSquare.getAppName();
}
public static void saveFile(String fileName, File sourceFile, Serializable serializable)
{
try
{
File tempFile;
if (Utils.isWindows())
tempFile = sourceFile;
else
tempFile = FileUtil.getTempFile("temp_" + fileName);
try (final FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream))
{
objectOutputStream.writeObject(serializable);
// Attempt to force the bits to hit the disk. In reality the OS or hard disk itself may still decide
// to not write through to physical media for at least a few seconds, but this is the best we can do.
fileOutputStream.flush();
fileOutputStream.getFD().sync();
} catch (IOException e)
{
e.printStackTrace();
log.error("save serializable object to file failed." + e);
if (tempFile.exists())
{
log.warn("Temp file still exists after failed save.");
if (!tempFile.delete())
{
log.warn("Cannot delete temp file.");
}
}
}
if (!Utils.isWindows())
{
if (!tempFile.renameTo(sourceFile))
{
log.error("Failed to rename " + tempFile.toString() + " to " + sourceFile.toString());
}
}
} catch (IOException e)
{
e.printStackTrace();
log.error("Exception at saveFile " + e);
}
}
public static void saveTempFileToFile(File tempFile, File file) throws IOException
{
if (Utils.isWindows())
{
// Work around an issue on Windows whereby you can't rename over existing files.
final File canonicalFile = file.getCanonicalFile();
if (canonicalFile.exists() && !canonicalFile.delete())
{
throw new IOException("Failed to delete pubKeyCanonicalFile for replacement with save");
}
if (!tempFile.renameTo(canonicalFile))
{
throw new IOException("Failed to rename " + tempFile + " to " + canonicalFile);
}
}
else
{
if (!tempFile.renameTo(file))
{
throw new IOException("Failed to rename " + tempFile + " to " + file);
}
}
}
}

View file

@ -1,6 +1,7 @@
package io.bitsquare.util;
import java.io.File;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,16 +43,24 @@ public class StorageDirectory
public static File getApplicationDirectory()
{
File executionRoot = new File(StorageDirectory.class.getProtectionDomain().getCodeSource().getLocation().getFile());
log.trace("executionRoot " + executionRoot.getAbsolutePath());
// check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar")
if (executionRoot.getAbsolutePath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty("os.name").startsWith("Mac"))
return executionRoot.getParentFile().getParentFile().getParentFile().getParentFile();
else if (executionRoot.getAbsolutePath().endsWith("/target/classes"))
return executionRoot.getParentFile(); // dev e.g.: /Users/mk/Documents/_intellij/bitsquare/target/classes -> use target as root
else if (executionRoot.getAbsolutePath().endsWith("/bitsquare.jar"))
return executionRoot.getParentFile(); // dev with jar e.g.: Users/mk/Documents/_intellij/bitsquare/out/artifacts/bitsquare2/bitsquare.jar -> use target as root
else
return executionRoot;
try
{
log.trace("executionRoot " + executionRoot.getCanonicalPath());
// check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar")
if (executionRoot.getCanonicalPath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty("os.name").startsWith("Mac"))
return executionRoot.getParentFile().getParentFile().getParentFile().getParentFile();
else if (executionRoot.getCanonicalPath().endsWith("/target/classes"))
return executionRoot.getParentFile(); // dev e.g.: /Users/mk/Documents/_intellij/bitsquare/target/classes -> use target as root
else if (executionRoot.getCanonicalPath().endsWith("/bitsquare.jar"))
return executionRoot.getParentFile(); // dev with jar e.g.: Users/mk/Documents/_intellij/bitsquare/out/artifacts/bitsquare2/bitsquare.jar -> use target as root
else
return executionRoot;
} catch (IOException e)
{
e.printStackTrace();
return null;
}
}