public static void append(Path zipPath, Path appendFilePath, CopyOption... options) throws IORuntimeException {
		try (FileSystem zipFileSystem = FileSystemUtil.createZip(zipPath.toString())) {
			if (Files.isDirectory(appendFilePath)) {
				Path source = appendFilePath.getParent();
				if (null == source) {
					// 如果用户提供的是根路径，则不复制目录，直接复制目录下的内容
					source = appendFilePath;
				}
				Files.walkFileTree(appendFilePath, new ZipCopyVisitor(source, zipFileSystem, options));
			} else {
				Files.copy(appendFilePath, zipFileSystem.getPath(PathUtil.getName(appendFilePath)), options);
			}
		} catch (FileAlreadyExistsException ignored) {
			// 不覆盖情况下，文件已存在, 跳过
		} catch (IOException e) {
			throw new IORuntimeException(e);
		}
	}
@Test
	public void appendTest() throws IOException {
		final File appendFile = FileUtil.file("test-zip/addFile.txt");
		final File zipFile = FileUtil.file("test-zip/test.zip");

		// 用于测试完成后将被测试文件恢复
		final File tempZipFile = FileUtil.createTempFile(FileUtil.file("test-zip"));
		tempZipFile.deleteOnExit();
		FileUtil.copy(zipFile, tempZipFile, true);

		// test file add
		List<String> beforeNames = zipEntryNames(tempZipFile);
		ZipUtil.append(tempZipFile.toPath(), appendFile.toPath());
		List<String> afterNames = zipEntryNames(tempZipFile);

		// 确认增加了文件
		assertEquals(beforeNames.size() + 1, afterNames.size());
		assertTrue(afterNames.containsAll(beforeNames));
		assertTrue(afterNames.contains(appendFile.getName()));

		// test dir add
		beforeNames = zipEntryNames(tempZipFile);
		final File addDirFile = FileUtil.file("test-zip/test-add");
		ZipUtil.append(tempZipFile.toPath(), addDirFile.toPath());
		afterNames = zipEntryNames(tempZipFile);

		// 确认增加了文件和目录，增加目录和目录下一个文件，故此处+2
		assertEquals(beforeNames.size() + 2, afterNames.size());
		assertTrue(afterNames.containsAll(beforeNames));
		assertTrue(afterNames.contains(appendFile.getName()));

		// rollback
		assertTrue(tempZipFile.delete(), String.format("delete temp file %s failed", tempZipFile.getCanonicalPath()));
	}