使用 Java 1.5 跨平台打开文件的方法

发布于 2024-07-09 16:36:14 字数 507 浏览 7 评论 0原文

我使用的是 Java 1.5,我想启动关联的应用程序来打开该文件。 我知道 Java 1.6 引入了 Desktop API,但我需要一个针对Java 1.5的解决方案。

到目前为止,我找到了一种在 Windows 中执行此操作的方法:

Runtime.getRuntime().exec(new String[]{ "rundll32", 
                          "url.dll,FileProtocolHandler", fileName });

Is there a cross-platform way to do it? 或者至少为 Linux 提供类似的解决方案?

I'm using Java 1.5 and I'd like to launch the associated application to open the file. I know that Java 1.6 introduced the Desktop API, but I need a solution for Java 1.5.

So far I found a way to do it in Windows:

Runtime.getRuntime().exec(new String[]{ "rundll32", 
                          "url.dll,FileProtocolHandler", fileName });

Is there a cross-platform way to do it? Or at least a similar solution for Linux?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

我爱人 2024-07-16 16:36:14
public static boolean isWindows() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("windows") != -1 || os.indexOf("nt") != -1;
}
public static boolean isMac() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("mac") != -1;
}
public static boolean isLinux() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("linux") != -1;
}
public static boolean isWindows9X() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.equals("windows 95") || os.equals("windows 98");
}

 if (isLinux())
  {
     cmds.add(String.format("gnome-open %s", fileName));
     String subCmd = (exec) ? "exec" : "openURL";
     cmds.add(String.format("kfmclient "+subCmd+" %s", fileName));
  }
  else if (isMac())
  {
     cmds.add(String.format("open %s", fileName));
  }
  else if (isWindows() && isWindows9X())
  {
     cmds.add(String.format("command.com /C start %s", fileName));
  }
  else if (isWindows())
  {
     cmds.add(String.format("cmd /c start %s", fileName));
  }
public static boolean isWindows() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("windows") != -1 || os.indexOf("nt") != -1;
}
public static boolean isMac() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("mac") != -1;
}
public static boolean isLinux() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.indexOf("linux") != -1;
}
public static boolean isWindows9X() {
    String os = System.getProperty("os.name").toLowerCase();
    return os.equals("windows 95") || os.equals("windows 98");
}

and

 if (isLinux())
  {
     cmds.add(String.format("gnome-open %s", fileName));
     String subCmd = (exec) ? "exec" : "openURL";
     cmds.add(String.format("kfmclient "+subCmd+" %s", fileName));
  }
  else if (isMac())
  {
     cmds.add(String.format("open %s", fileName));
  }
  else if (isWindows() && isWindows9X())
  {
     cmds.add(String.format("command.com /C start %s", fileName));
  }
  else if (isWindows())
  {
     cmds.add(String.format("cmd /c start %s", fileName));
  }
白色秋天 2024-07-16 16:36:14

JDIC 是一个在 Java 1.5 中提供类似桌面功能的库。

JDIC is a library that provides Desktop-like functionality in Java 1.5.

楠木可依 2024-07-16 16:36:14

+1 这个答案

另外,我建议使用多态性进行以下实现:

这样您可以通过减少类之间的耦合。

客户端代码:

 Desktop desktop = Desktop.getDesktop();

 desktop.open( aFile );
 desktop.imaginaryAction( aFile );

桌面实现:

package your.pack.name;

import java.io.File;

public class Desktop{

    // hide the constructor.
    Desktop(){}

    // Created the appropriate instance
    public static Desktop getDesktop(){

        String os = System.getProperty("os.name").toLowerCase();

        Desktop desktop = new Desktop();
         // This uf/elseif/else code is used only once: here
        if ( os.indexOf("windows") != -1 || os.indexOf("nt") != -1){

            desktop = new WindowsDesktop();

        } else if ( os.equals("windows 95") || os.equals("windows 98") ){

            desktop = new Windows9xDesktop();

        } else if ( os.indexOf("mac") != -1 ) {

            desktop = new OSXDesktop();

        } else if ( os.indexOf("linux") != -1 && isGnome() ) {

            desktop = new GnomeDesktop();

        } else if ( os.indexOf("linux") != -1 && isKde() ) {

            desktop = new KdeDesktop();

        } else {
            throw new UnsupportedOperationException(String.format("The platform %s is not supported ",os) );
        }
        return desktop;
    }

    // default implementation :( 
    public void open( File file ){
        throw new UnsupportedOperationException();
    }

    // default implementation :( 
    public void imaginaryAction( File file  ){
        throw new UnsupportedOperationException();
    }
}

// One subclass per platform below:
// Each one knows how to handle its own platform   


class GnomeDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: execute gnome-open <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec:gnome-something-else <file>
    }

}
class KdeDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: kfmclient exec <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: kfm-imaginary.sh  <file>
    }
}
class OSXDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: open <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: wow!! <file>
    }
}
class WindowsDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: cmd /c start <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: ipconfig /relese /c/d/e
    }
}
class Windows9xDesktop extends Desktop{

    public void open( File file ){
        //Runtime.getRuntime().exec: command.com /C start <file>
    }

    public void imaginaryAction( File file){
       //Runtime.getRuntime().exec: command.com /C otherCommandHere <file>
    }
}

这只是一个示例,在现实生活中不值得创建一个新类只是为了参数化一个值(命令字符串 %s )但是让我们想象一下每个方法都以特定于平台的方式执行其他步骤。

采取这种方法,可能会删除不需要的 if/elseif/else 结构,随着时间的推移,这些结构可能会引入错误(如果代码中有 6 个这样的结构并且需要更改,您可能会忘记更新其中一个,或者通过复制/粘贴时你可能会忘记更改要执行的命令)

+1 for this answer

Additionally I would suggest the following implementation using polymorphism:

This way you can add new platform easier by reducing coupling among classes.

The Client code:

 Desktop desktop = Desktop.getDesktop();

 desktop.open( aFile );
 desktop.imaginaryAction( aFile );

The Desktop impl:

package your.pack.name;

import java.io.File;

public class Desktop{

    // hide the constructor.
    Desktop(){}

    // Created the appropriate instance
    public static Desktop getDesktop(){

        String os = System.getProperty("os.name").toLowerCase();

        Desktop desktop = new Desktop();
         // This uf/elseif/else code is used only once: here
        if ( os.indexOf("windows") != -1 || os.indexOf("nt") != -1){

            desktop = new WindowsDesktop();

        } else if ( os.equals("windows 95") || os.equals("windows 98") ){

            desktop = new Windows9xDesktop();

        } else if ( os.indexOf("mac") != -1 ) {

            desktop = new OSXDesktop();

        } else if ( os.indexOf("linux") != -1 && isGnome() ) {

            desktop = new GnomeDesktop();

        } else if ( os.indexOf("linux") != -1 && isKde() ) {

            desktop = new KdeDesktop();

        } else {
            throw new UnsupportedOperationException(String.format("The platform %s is not supported ",os) );
        }
        return desktop;
    }

    // default implementation :( 
    public void open( File file ){
        throw new UnsupportedOperationException();
    }

    // default implementation :( 
    public void imaginaryAction( File file  ){
        throw new UnsupportedOperationException();
    }
}

// One subclass per platform below:
// Each one knows how to handle its own platform   


class GnomeDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: execute gnome-open <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec:gnome-something-else <file>
    }

}
class KdeDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: kfmclient exec <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: kfm-imaginary.sh  <file>
    }
}
class OSXDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: open <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: wow!! <file>
    }
}
class WindowsDesktop extends Desktop{

    public void open( File file ){
        // Runtime.getRuntime().exec: cmd /c start <file>
    }

    public void imaginaryAction( File file ){
        // Runtime.getRuntime().exec: ipconfig /relese /c/d/e
    }
}
class Windows9xDesktop extends Desktop{

    public void open( File file ){
        //Runtime.getRuntime().exec: command.com /C start <file>
    }

    public void imaginaryAction( File file){
       //Runtime.getRuntime().exec: command.com /C otherCommandHere <file>
    }
}

This is only an example, in real life is not worth to create a new class only to parametrize a value ( the command string %s ) But let's do imagine that each method performs another steps in platform specific way.

Doing this kind of approach, may remove unneeded if/elseif/else constructs that with time may introduce bugs ( if there are 6 of these in the code and a change is neede, you may forget to update one of them, or by copy/pasting you may forget to change the command to execute)

黎夕旧梦 2024-07-16 16:36:14

作为补充:不要使用 gnome-open,而是使用 xdg-open。 它是 XdgUtils 的一部分,而 XdgUtils 又是 LSB 桌面支持包的一部分(从 3.2 开始) )。

您仍然可以(应该)使用 gnome-open 作为后备,但 xdg-open 也可以在非 GNOME 桌面上运行。

Just as an addition: Rather than gnome-open, use xdg-open. It's part of the XdgUtils, which are in turn part of the LSB Desktop support package (starting with 3.2).

You can (should) still use gnome-open as a fallback, but xdg-open will also work on non-GNOME desktops.

流心雨 2024-07-16 16:36:14

SWT 使您可以通过以下方式查找标准程序打开文件:

final Program p = Program.findProgram(fileExtension);
p.execute(file.getAbsolutePath());

严格来说这不是'跨平台,因为 SWT 依赖于平台,但对于每个平台,您可以使用不同的 SWT jar。

SWT gives you the possibility to lokk for the standard program to open a file via:

final Program p = Program.findProgram(fileExtension);
p.execute(file.getAbsolutePath());

Strictly this isn't Cross-Platform since SWT is platform dependent, but for every platform you can use a diffenrent SWT jar.

波浪屿的海角声 2024-07-16 16:36:14

您可以使用操作系统默认的方式为您打开它。

  • Windows:“cmd /c 文件名
  • Linux w/gnome“gnome-open 文件名
  • Linux w/Kde ??
  • OSx“打开文件名

You can use the OS default way to open it for you.

  • Windows: "cmd /c fileName
  • Linux w/gnome "gnome-open filename"
  • Linux w/Kde ??
  • OSx "open filename"
没有你我更好 2024-07-16 16:36:14

另一个答案(由 boutta)建议使用 SWT。 我不建议仅出于此目的引用该库,但如果您已经在使用它,只需执行:

Program.launch("http://google.com/");

请注意,此方法仅在 Display 时才有效(并返回 true 对象已创建(例如通过创建 Shell)。 另请注意,它必须在主线程中运行; 例如:

Display.syncExec(new Runnable() {
    public void run() {
        Program.launch("http://google.com/");
    }
});

在上面的示例中,我启动了一个 URL,但启动文件的方式相同。

Another answer (by boutta) suggests using SWT. I wouldn't recommend referencing the library for this purpose only, but if you are using it already, simply execute:

Program.launch("http://google.com/");

Take note that this method will only work (and return true) if a Display object has already been created (for instance by creating a Shell). Also take note that it must run in the main thread; e.g.:

Display.syncExec(new Runnable() {
    public void run() {
        Program.launch("http://google.com/");
    }
});

In the example above I've launched a URL, but launching files works in the same way.

酸甜透明夹心 2024-07-16 16:36:14

我们确实将该命令放在配置文件中的某个位置之外。

您的“JAR 和源代码”将是“跨平台的”,但您的部署却不是。

您还可以执行类似此答案。 您可以将“Deskop”实现的工厂类的类名放入安装文件中。 (如果你愿意的话,可以是指南或弹簧)

We do put the command outside somewhere in the configuration file.

Your "JAR and source code" will be "cross-platform", but your deployment doesn't.

You can also do something like this answer. You can put the classname of the factory class of the "Deskop" implementation into the setup file. (may be guide or spring, if you like)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文