创建更新程序
Creating an Updater
我目前正在尝试为我正在编写的应用程序实施更新程序。
该过程目前看起来如下:
- 从类路径(例如app.jar)中提取updater.jar到系统的临时目录
- 打开一个套接字来监听更新程序的终止请求
- 开始 updater.jar
- 更新器然后检查更新器是否可用
- 如果更新可用,更新程序会向应用程序发送终止请求(通过打开的套接字)
- 更新程序将新版本下载到系统临时目录
- 更新程序将所有文件从新版本复制到应用程序的基本目录(覆盖现有文件)
此过程中有问题的部分是将新版本的文件副本复制到应用程序的基目录中,因为应用基目录中的某些文件可能由于某种原因被锁定(即用户在此目录中打开文件)。
因此,可能会发生一些文件已被复制而一些文件尚未复制的情况 - 留下不一致的状态并且可能无法执行应用程序。
我为防止这种情况所做的是在复制新文件之前检查应用程序的 basedir 中是否有任何锁定的文件。我为此编写了一个 util 方法:
public static boolean isLocked(File pFile){
if (pFile == null || !pFile.exists()){
return false;
}
if (!pFile.canWrite()) return true;
if (!pFile.renameTo(pFile)) return true;
try {
final FileChannel tFileChannel = FileChannel.open(pFile.toPath(), StandardOpenOption.WRITE);
final FileLock tLock = tFileChannel.tryLock();
try {
if (tLock == null){
return true;
} else {
tLock.release();
}
} finally {
tFileChannel.close();
}
} catch (final IOException | OverlappingFileLockException ex) {
return true;
}
return false;
}
但我仍然认为这个过程很容易出错,因为我不知道 isLocked()
方法是否在所有情况下都能提供可靠的结果。
即使这样,锁定状态也仅在调用该方法时有效 -> 文件可能会在调用后立即被锁定(例如,通过防病毒扫描程序)。
所以我的问题是:是否有更可靠的方法来复制一组文件?也许在某种可回滚的文件事务中?
也许我忽略了一些东西——但这不是确保您的更新程序在开始工作之前锁定所有文件的唯一正确答案吗?
它试图锁定所有文件;只有当它 "owns" 所有相关文件时,它才会开始工作?!
我目前正在尝试为我正在编写的应用程序实施更新程序。 该过程目前看起来如下:
- 从类路径(例如app.jar)中提取updater.jar到系统的临时目录
- 打开一个套接字来监听更新程序的终止请求
- 开始 updater.jar
- 更新器然后检查更新器是否可用
- 如果更新可用,更新程序会向应用程序发送终止请求(通过打开的套接字)
- 更新程序将新版本下载到系统临时目录
- 更新程序将所有文件从新版本复制到应用程序的基本目录(覆盖现有文件)
此过程中有问题的部分是将新版本的文件副本复制到应用程序的基目录中,因为应用基目录中的某些文件可能由于某种原因被锁定(即用户在此目录中打开文件)。
因此,可能会发生一些文件已被复制而一些文件尚未复制的情况 - 留下不一致的状态并且可能无法执行应用程序。
我为防止这种情况所做的是在复制新文件之前检查应用程序的 basedir 中是否有任何锁定的文件。我为此编写了一个 util 方法:
public static boolean isLocked(File pFile){
if (pFile == null || !pFile.exists()){
return false;
}
if (!pFile.canWrite()) return true;
if (!pFile.renameTo(pFile)) return true;
try {
final FileChannel tFileChannel = FileChannel.open(pFile.toPath(), StandardOpenOption.WRITE);
final FileLock tLock = tFileChannel.tryLock();
try {
if (tLock == null){
return true;
} else {
tLock.release();
}
} finally {
tFileChannel.close();
}
} catch (final IOException | OverlappingFileLockException ex) {
return true;
}
return false;
}
但我仍然认为这个过程很容易出错,因为我不知道 isLocked()
方法是否在所有情况下都能提供可靠的结果。
即使这样,锁定状态也仅在调用该方法时有效 -> 文件可能会在调用后立即被锁定(例如,通过防病毒扫描程序)。
所以我的问题是:是否有更可靠的方法来复制一组文件?也许在某种可回滚的文件事务中?
也许我忽略了一些东西——但这不是确保您的更新程序在开始工作之前锁定所有文件的唯一正确答案吗?
它试图锁定所有文件;只有当它 "owns" 所有相关文件时,它才会开始工作?!