fix windows file rename bug

This commit is contained in:
Manfred Karrer 2014-07-09 13:56:17 +02:00
parent 2778779414
commit ec494136ed
4 changed files with 49 additions and 69 deletions

View file

@ -53,7 +53,7 @@ public class Storage
lock.lock(); lock.lock();
try try
{ {
FileUtil.saveFile(prefix, storageFile, (Serializable) rootMap); saveObjectToFile((Serializable) rootMap);
} finally } finally
{ {
lock.unlock(); lock.unlock();
@ -119,7 +119,7 @@ public class Storage
{ {
lock.lock(); lock.lock();
rootMap.put(key, value); rootMap.put(key, value);
FileUtil.saveFile(prefix, storageFile, (Serializable) rootMap); saveObjectToFile((Serializable) rootMap);
} finally } finally
{ {
lock.unlock(); lock.unlock();
@ -216,6 +216,42 @@ 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();
FileUtil.writeTempFileToFile(tempFile, 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 private Object readObjectFromFile(File file) throws IOException, ClassNotFoundException
{ {

View file

@ -7,7 +7,6 @@ import java.awt.*;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.stage.Stage; import javafx.stage.Stage;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -43,8 +42,6 @@ public class AWTSystemTray
trayIcon.setPopupMenu(popupMenu); trayIcon.setPopupMenu(popupMenu);
trayIcon.addActionListener(e -> JOptionPane.showMessageDialog(null, "This dialog box is run from System Tray"));
showGuiItem.addActionListener(e -> { showGuiItem.addActionListener(e -> {
if (isStageVisible) if (isStageVisible)
{ {

View file

@ -114,8 +114,8 @@ public class DSAKeyUtil
privKeyFileOutputStream.getFD().sync(); privKeyFileOutputStream.getFD().sync();
FileUtil.saveTempFileToFile(pubKeyTempFile, pubKeyFile); FileUtil.writeTempFileToFile(pubKeyTempFile, pubKeyFile);
FileUtil.saveTempFileToFile(privKeyTempFile, privKeyFile); FileUtil.writeTempFileToFile(privKeyTempFile, privKeyFile);
} finally } finally
{ {
if (pubKeyTempFile.exists()) if (pubKeyTempFile.exists())

View file

@ -2,7 +2,9 @@ package io.bitsquare.util;
import com.google.bitcoin.core.Utils; import com.google.bitcoin.core.Utils;
import io.bitsquare.BitSquare; import io.bitsquare.BitSquare;
import java.io.*; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -53,70 +55,15 @@ public class FileUtil
return BitSquare.getAppName(); return BitSquare.getAppName();
} }
public static void saveFile(String fileName, File sourceFile, Serializable serializable) public static void writeTempFileToFile(File tempFile, File file) throws IOException
{
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()) if (Utils.isWindows())
{ {
// Work around an issue on Windows whereby you can't rename over existing files. // renameTo fails on win 8
final File canonicalFile = file.getCanonicalFile(); String canonicalPath = file.getCanonicalPath();
if (canonicalFile.exists() && !canonicalFile.delete()) file.delete();
{ final File canonicalFile = new File(canonicalPath);
throw new IOException("Failed to delete pubKeyCanonicalFile for replacement with save"); Files.copy(tempFile.toPath(), canonicalFile.toPath());
}
if (!tempFile.renameTo(canonicalFile))
{
throw new IOException("Failed to rename " + tempFile + " to " + canonicalFile);
}
} }
else else
{ {