如何让 OS X 识别驱动器号?
我知道。异端。但我陷入了困境。我有很多使用绝对路径名的配置文件,这导致 OS X 和 Windows 之间不兼容。如果我能让 OS X(我打赌这是两者中更灵活的)将 Q:/foo/bar/bim.properties 识别为有效的绝对文件名,它将保存我花了天的时间通过堆栈跟踪和配置文件进行探索。
最后,我需要这段 Java 测试代码来打印“SUCCESS!”当它运行时:
import java.io.*;
class DriveLetterTest {
static public void main(String... args) {
File f = new File("S:");
if (f.isDirectory()) {
System.out.println("SUCCESS!");
} else {
System.out.println("FAIL!");
}
}
}
有人知道这是如何做到的吗?
更新:感谢大家的所有反馈。现在对我来说很明显我真的应该更清楚地表达我的问题。
配置文件和使用它们的代码都属于我无法更改的第三方包。 (嗯,我可以更改它们,但这意味着会产生持续的维护负载,如果可能的话我想避免这种情况。)
我完全同意所有的观点对这种事态感到震惊的你们。但事实仍然是:我无法更改第三方代码,而且我真的想避免分叉配置文件。
I know. Heresy. But I'm in a bind. I have a lot of config files that use absolute path names, which creates an incompatibility between OS X and Windows. If I can get OS X (which I'm betting is the more flexible of the two) to recognize Q:/foo/bar/bim.properties as a valid absolute file name, it'll save me days of work spelunking through stack traces and config files.
In the end, I need this bit of Java test code to print "SUCCESS!" when it runs:
import java.io.*;
class DriveLetterTest {
static public void main(String... args) {
File f = new File("S:");
if (f.isDirectory()) {
System.out.println("SUCCESS!");
} else {
System.out.println("FAIL!");
}
}
}
Anyone know how this can be done?
UPDATE: Thanks for all the feedback, everyone. It's now obvious to me I really should have been clearer in my question.
Both the config files and the code that uses them belong to a third-party package I cannot change. (Well, I can change them, but that means incurring an ongoing maintenance load, which I want to avoid if at all possible.)
I'm in complete agreement with all of you who are appalled by this state of affairs. But the fact remains: I can't change the third-party code, and I really want to avoid forking the config files.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
简短回答:不。
长答案:对于Java,您应该使用
System.getProperties(XXX)
。然后,您可以根据在
os.name
中找到的内容加载属性文件或配置。替代解决方案只需在读取非 Windows 计算机上的现有配置文件时去掉
S:
并将其替换为适当的内容即可。意见:就我个人而言,我现在会咬紧牙关处理技术债务,在构建 OSX 部署时修复所有配置文件并完成它。
我的 iMac 上的输出是:
Short answer: No.
Long answer: For Java you should use
System.getProperties(XXX)
.Then you can load a Properties file or Configuration based on what you find in
os.name
.Alternate Solution just strip off the
S:
when you read the existing configuration files on non-Windows machines and replace them with the appropriate things.Opinion: Personally I would bite the bullet and deal with the technical debt now, fix all the configuration files at build time when the deployment for OSX is built and be done with it.
the output on my iMac is:
老实说,不要在程序中硬编码绝对路径,即使对于单平台应用程序也是如此。做正确的事。
以下是我的错误解决方案,保存是为了提醒自己不要重复给出错误的建议……我真丢脸。
只需创建一个名为Q:
的 符号链接根目录/
到/
本身。您可能需要使用
sudo
。然后,在程序开始时,只需将chdir
更改为/
。如果您不希望
Q:
和S:
显示在 Finder 中,请执行设置文件对 Finder 不可见的位.Honestly, don't hard-code absolute paths in a program, even for a single-platform app. Do the correct thing.
The following is my wrong solution, saved to remind myself not to repeat giving a misdirected advice ... shame on me.
Just create a symbolic link namedQ:
just at the root directory/
to/
itself.You might need to use
sudo
. Then, at the start of your program, justchdir
to/
.If you don't want
Q:
andS:
to show up in the Finder, performwhich set the invisible-to-the-Finder bit of the files.刚刚测试了一些东西,发现了一些有趣的事情:在Windows中,如果当前目录位于同一个逻辑卷上(即root是相同的驱动器号),则在使用路径时可以省略驱动器号。因此,您可以删除所有这些驱动器号和冒号,只要您不使用不同磁盘上项目的路径,就应该没问题。
Just tested something out, and discovered something interesting: In Windows, if the current directory is on the same logical volume (i.e. root is the same drive letter), you can leave off the drive letter when using a path. So you could just trim off all those drive letters and colons and you should be fine as long as you aren't using paths to items on different disks.
替换 java.io.File 的唯一方法是替换 rt.jar 中的该类。
我不建议这样做,但最好的方法是获取 OpenJDK 代码,进行必要的更改,构建它并在您的项目中重新分发二进制文件。编写一个 shell 脚本来使用您自己的 java 二进制文件,而不是内置的二进制文件。
附言。只需更改您的配置文件即可!练习您的正则表达式技能并为自己节省大量时间。
The only way you can replace java.io.File is to replace that class in rt.jar.
I don't recommend that, but the best way to do this is to grab a bsd-port of the OpenJDK code, make necessary changes, build it and redistribute the binary with your project. Write a shell script to use your own java binary and not the built-in one.
PS. Just change your config files! Practice your regex skills and save yourself a lot of time.
如果您不愿意更改每个操作系统的配置文件,那么它们首先是用来做什么的?
每个安装都应该有自己的一组配置文件并相应地使用它。
但如果你坚持..你只需要检测操作系统版本,如果不是Windows,请忽略这封信:
大意是:
你明白了
If you are not willing to change your config file per OS, what are they for in first place?
Every installation should have its own set of config files and use it accordingly.
But if you insist.. you just have to detect the OS version and if is not Windows, ignore the letter:
Something along the lines:
You get the idea
您很可能必须提供一种不同的
java.io.File
实现来正确解析文件路径,也许有人已经制作了一个。真正的解决方案是将这种东西(硬编码的文件路径)放在配置文件中,而不是放在源代码中。
Most likely you'd have to provide a different
java.io.File
implementation that can parse out the file paths correctly, maybe there's one someone already made.The real solution is to put this kind of stuff (hard-coded file paths) in configuration files and not in the source code.
这就是我最终所做的:
我下载了 java.io 包的源代码,并调整了 java.io.File 的代码以查找以字母和冒号开头的路径名。如果找到,它会在路径名前面加上“/Volumes/”,向 System.err 发出警告,然后照常继续。
我已将 /Volumes 下的符号链接添加到我需要映射的“驱动器”,因此我有:
我将其放入自己的 jar 中,并将该 jar 放在类路径的前面仅此项目。这样,黑客攻击就只影响我,也只影响这个项目。
最终结果:java.io.File 看到类似“S:/bling.properties”的路径,然后检查操作系统。如果操作系统是 OS X,它会在前面添加“/Volumes/”,并在 /Volumes/S:/bling.properties 中查找文件,这很好,因为它可以只遵循符号链接。
是啊,实在是太丑了。但它完成了今天的工作。
Here's what I finally ended up doing:
I downloaded the source code for the java.io package, and tweaked the code for java.io.File to look for path names that start with a letter and a colon. If it finds one, it prepends "/Volumes/" to the path name, coughs a warning into System.err, then continues as normal.
I've added symlinks under /Volumes to the "drives" I need mapped, so I have:
I put it into its own jar, and put that jar at the front of the classpath for this project only. This way, the hack affects only me, and only this project.
Net result: java.io.File sees a path like "S:/bling.properties", and then checks the OS. If the OS is OS X, it prepends "/Volumes/", and looks for a file in /Volumes/S:/bling.properties, which is fine, because it can just follow the symlink.
Yeah, it's ugly as hell. But it gets the job done for today.