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();
try
{
FileUtil.saveFile(prefix, storageFile, (Serializable) rootMap);
saveObjectToFile((Serializable) rootMap);
} finally
{
lock.unlock();
@ -119,7 +119,7 @@ public class Storage
{
lock.lock();
rootMap.put(key, value);
FileUtil.saveFile(prefix, storageFile, (Serializable) rootMap);
saveObjectToFile((Serializable) rootMap);
} finally
{
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
{

View File

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

View File

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

View File

@ -2,7 +2,9 @@ package io.bitsquare.util;
import com.google.bitcoin.core.Utils;
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.LoggerFactory;
@ -53,70 +55,15 @@ public class FileUtil
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
public static void writeTempFileToFile(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);
}
// renameTo fails on win 8
String canonicalPath = file.getCanonicalPath();
file.delete();
final File canonicalFile = new File(canonicalPath);
Files.copy(tempFile.toPath(), canonicalFile.toPath());
}
else
{