11

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

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

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

有跨平台的方法吗?或者至少有一个类似的Linux解决方案?

4

8 回答 8

13
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));
  }
于 2008-11-28T11:15:01.967 回答
12

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

于 2008-11-28T11:46:56.883 回答
11

对此答案+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 个这样的结构并且需要更改,您可能会忘记更新其中一个,或者通过复制 /粘贴您可能会忘记更改要执行的命令)

于 2008-11-28T18:14:42.950 回答
5

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

您可以(应该)仍将gnome-open其用作后备,但xdg-open也可以在非 GNOME 桌面上工作。

于 2008-11-28T23:45:54.873 回答
4

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

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

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

于 2008-11-28T08:58:28.623 回答
0

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

  • Windows:“cmd /c文件名
  • Linux w/gnome “gnome-open文件名
  • Linux w/Kde ??
  • OSx“打开文件名
于 2008-11-28T09:05:00.140 回答
0

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

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

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

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

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

于 2010-11-17T19:19:31.143 回答
-3

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

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

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

于 2008-11-28T18:22:55.773 回答