[英]Dealing with unix symlink files on Windows filesystem
我目前正在开发一个 Java 项目,该项目应该允许用户导出与 Windows 软件 (.exe) 或 OS X 应用程序 (.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去做这样的系统特定任务。 可能你不必。
取决于您在此项目中的角色,您可以重新定义应包含的包。 你真的需要里面的符号链接吗? 可能更普遍的是有一些将不同部分映射在一起的“属性”文件? 或者将其作为数据库分发? 尽量不要依赖于系统特定的实现。
您将需要Windows特定的“非标准”(至少用于Java)方法来解决此问题,因为没有标准的跨平台Java方法来解决它。 例如,您可以尝试使用Runtime.exec
以及对“mklink”实用程序的调用。 “mklink”命令允许创建硬和软(符号)链接以及结点的创建 - 基本上它创建了Windows文件系统可用的各种类型的重新解析点。 如果您愿意访问本机代码,那么您也可以使用预先制作的JNA映射到Kernel32.dll
或编写自定义映射到Kernel32.dll
并调用WinBase.h
提供的方法CreateSymbolicLink(LPTSTR,LPTSTR,DWORD)
。
一般来说,如果可能的话,我建议你尽量避免使用Windows上的符号链接和硬链接。
Symlinks和Hardlinks已经很晚才被引入Windows,对它的支持相当差:
因此,由于您只需要临时(如您在评论中所写)的符号链接,然后再次压缩文件,我建议在解压缩时创建自己的标记文件以表示符号链接,稍后在压缩时将其转换回来到ZIP文件中正确的UNIX符号链接。
已经 6 年了,如果你在 Windows 上压缩 macOS 应用程序包,然后在 Windows 上解压相同的 ZIP,它会保留 macOS 包中的别名文件(主要在 Frameworks 文件夹中)。
正如您所说,您还可以将 macOS 应用程序保留为 ZIP package,并让用户在需要时将其解压缩(最有可能在 macOS 上),那么它也可以工作。
在 Linux 上压缩 macOS 应用程序包并在 macOS 上解压缩也可以,但在 Windows 上不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.