Java桌面程序更新实现

I'm Shendi


最近在写控制台软件,客户端软件,于是就需要增加更新模块,在这里记录一下

目录

思路

实现

解压实现更新(补充)


思路

首先是服务端和客户端进行通信,一般通过校验版本来判断是否需要更新

如果需要更新则获取需要更新的文件

更新分为几种类型,通过服务端发来的消息来判断,

  • 可选更新
  • 强制更新(自动更新)

在代码方面,一般都是直接打包成jar,于是直接下载替换就行

其余的配置文件方面的也是如此,通过相对路径

在更新完毕后重新启动.

如果不想重新启动则可以使用自定义类加载器来实现热更新.

实现

这里直接使用控制台

从服务端获取的操作直接省略了(这里需要自己根据自己的需求来对应处理)

代码如下(旧)

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test {
	public static void main(String[] args) throws Exception {
		// 模拟,需要更新则执行
		if (true) {
			// 获取到要更新的文件,这里替换成从服务器获取要更新的文件
			FileInputStream input = new FileInputStream("../Test.class");
			byte[] data = new byte[input.available()];
			input.read(data);
			input.close();
			// 替换
			FileOutputStream output = new FileOutputStream("Test.class");
			output.write(data);
			output.close();
			// 重新启动
			Runtime.getRuntime().exec("cmd /c start java Test");
			System.exit(0);
		}
		System.out.println("测试,更新前");
		// 方便显示,不然窗口弹出就会消失
		while (true) {}
	}
	
}

新版

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test {
	public static void main(String[] args) throws Exception {
		// 模拟,需要更新则执行
		if (false) {
			// 获取到要更新的文件,这里替换成从服务器获取要更新的文件
			FileInputStream input = new FileInputStream("../Test.class");
			byte[] data = new byte[input.available()];
			input.read(data);
			input.close();
			// 替换
			FileOutputStream output = new FileOutputStream("Test.class");
			output.write(data);
			output.close();
			// 重新启动
			Runtime.getRuntime().exec("cmd /c start java Test");
			System.exit(0);
		}
		System.out.println("测试,更新后");
		// 方便显示
		while (true) {}
	}
	
}

目录结构如下

然后我们编译

到client目录下运行,于是可以看到如下

这时 更新就完成了.

最后,推荐一下我写的工具包(更新时替换文件操作可以使用此工具包的FileUtil类)

https://github.com/1711680493/ShendiKit

解压实现更新(补充附加代码)

上面提供的是思路,下面提供的是一种实用性的更新方式

首先看效果

 

此种方式使用解压缩包的方式进行更新(JDK 支持zip,不需要第三方jar包)

思路:有一个jar专门用于更新,当需要更新则从服务器下载压缩包(zip,压缩包内容为需要更新的文件),且将压缩包解压到对应目录,覆盖旧的文件,再启动更新后的jar包以达到更新效果

解压缩代码如下

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * 更新工具,用于检测/进行更新.
 * <br>
 * 创建时间 2021年8月21日 下午6:57:37
 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
 * @version 1.0
 */
public class Update {

	public static void main(String[] args) throws IOException {
		// TODO 从服务器下载要更新的文件压缩包(zip),下载完后保存到指定目录
		// 解压目录,这里取项目根目录
		String unzipPath = System.getProperty("user.dir");
		
		// 解压文件到当前文件夹,替换对应文件
		ZipFile zip = new ZipFile(unzipPath.concat("/update.zip"));
		System.out.println(zip.size());
		Enumeration<? extends ZipEntry> e = zip.entries();
		while (e.hasMoreElements()) {
			ZipEntry ele = e.nextElement();
			
			// 文件路径
			String path = unzipPath.concat(File.separatorChar + ele.getName());
			
			if (ele.isDirectory()) {
				// 目录则判断是否存在, 不存在则创建
				File f = new File(path);
				if (!f.exists()) f.mkdirs();
			} else {
				// 文件则直接解压到指定目录,有对应文件直接替换
				System.out.println("文件被替换了:" + path);
				FileOutputStream fo = new FileOutputStream(path);
				InputStream input = zip.getInputStream(ele);
				
				byte[] data = new byte[input.available()];
				input.read(data, 0, data.length);
				
				fo.write(data);
				fo.close();
			}
		}
		
		zip.close();
		// 解压完成=更新完成,运行启动类的jar后退出
		Runtime.getRuntime().exec("cmd /c start java -jar test.jar");
		System.exit(0);
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HackShendi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值