code: private static void zip(File file, String srcRootDir, ZipOutputStream out) throws UtilException {
  		if (file == null) {
  			return;
  		}
  
  		final String subPath = FileUtil.subPath(srcRootDir, file); // 获取文件相对于压缩文件夹根目录的子路径
  		if (file.isDirectory()) {// 如果是目录，则压缩压缩目录中的文件或子目录
  			final File[] files = file.listFiles();
  			if (ArrayUtil.isEmpty(files) && StrUtil.isNotEmpty(subPath)) {
  				// 加入目录，只有空目录时才加入目录，非空时会在创建文件时自动添加父级目录
  				addDir(subPath, out);
  			}
  			// 压缩目录下的子文件或目录
  			for (File childFile : files) {
  				zip(childFile, srcRootDir, out);
  			}
  		} else {// 如果是文件或其它符号，则直接压缩该文件
  			addFile(file, subPath, out);
  		}
  	}
docs: 递归压缩文件夹<br>
  srcRootDir决定了路径截取的位置，例如：<br>
  file的路径为d:/a/b/c/d.txt，srcRootDir为d:/a/b，则压缩后的文件与目录为结构为c/d.txt
  
  @param out 压缩文件存储对象
  @param srcRootDir 被压缩的文件夹根目录
  @param file 当前递归压缩的文件或目录对象
  @throws UtilException IO异常