我目前正在开发一个Java项目,该项目应该允许用户导出与Windows软件(.exe)或OS X app(.app)捆绑在一起的项目,以将数据分发到其他工作站. Windows和OS X软件都存储为压缩zip文件,并在导出项目时解压缩.我的问题是在Windows上解压缩OS X应用程序打破了捆绑框架内的符号链接.反过来,这会破坏应用程序的签名,并在OS X上启动应用程序时导致问题.
我正在使用Apache Commons压缩库解压缩包,这使我能够检测符号链接及其目标.使用OS X,我能够使用java.nio.file.Files中的方法重新创建符号链接,但是对于Windows,这将需要管理员权限,我有点犹豫要添加作为使用该软件的先决条件(即使启用我也不相信这会起作用 – 没试过).
我对链接被破坏的原因有一点了解,但如果我理解正确,Windows文件系统不包括对Unix符号链接的文件类型的支持,因此链接被解压缩为普通文件,将不再在OS X上打开时被识别为符号链接.
所以,我的问题是,我能以某种方式将符号链接文件按位按位复制到Windows文件系统,保留Unix特定位或者保留这些信息是不可能的吗?或者我应该只更改导出方法以将项目文件添加到现有的zip文件,在这种情况下,可能会保留符号链接信息,直到在目标计算机上解压缩zip?
在ZipFile的每个ZipArchiveEntry上循环的当前代码如下:
byte data[] = new byte[BUFFER];
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry zipEntry = entries.nextElement();
String destFilename = copyFolder + zipEntry.getName();
File destFile = new File(destFilename);
if (zipEntry.isUnixSymlink()) {
File target = new File(zipFile.getUnixSymlink(zipEntry));
try {
// Try to create symbolic link - currently only works with OS X
Files.createSymbolicLink(destFile.toPath(), target.toPath());
continue;
} catch (Exception e) {
System.out.println("Failed to create symbolic link: " +
destFile.getAbsolutePath() + " -> " +
target.getAbsolutePath());
}
}
// If file
int count;
FileOutputStream fos = new FileOutputStream(destFile);
try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) {
InputStream is = zipFile.getInputStream(zipEntry);
while ( (count = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
}
}
解决方法:
Windows文件系统使用与UNIX类似的方法来定义符号链接(如硬链接或软链接),但它们不是100%兼容的.你可以在这里阅读更多相关信息:https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680(v=vs.85).aspx
你问的简单答案 – 你不能只是按位复制链接以获得相同的Unix特定位,因为Windows NTFS只是没有它们. JAVA也设计为在沙箱中工作,因此您无法访问系统低级API以“制作”您想要的任何内容.我不会用JAVA去做这样的系统特定任务.可能你不必.
取决于您在此项目中的角色,您可以重新定义应包含的包.你真的需要里面的符号链接吗?可能更普遍的是有一些将不同部分映射在一起的“属性”文件?或者将其作为数据库分发?尽量不要依赖于系统特定的实现.