Кросс-платформенный способ открытия файла с помощью Java 1.5

Я использую Java 1.5 и хочу запустить соответствующее приложение, чтобы открыть файл. Я знаю, что в Java 1.6 появился Desktop API, но мне нужно решение для Java 1.5.

Пока что нашел способ сделать это в Windows:

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

Есть ли кроссплатформенный способ сделать это? Или хотя бы аналогичное решение для Linux?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
11
0
12 045
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

SWT дает вам возможность заблокировать стандартную программу для открытия файла через:

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

Строго говоря, это не кроссплатформенность, поскольку SWT зависит от платформы, но для каждой платформы вы можете использовать различную банку SWT.

Примечание: источник Program.java находится здесь kickjava.com/src/org/eclipse/swt/program/Program.java.htm. Может быть, это тоже может помочь

VonC 28.11.2008 12:15

Вероятно, это очень полезно для пользователей Java 1.5 + SWT. Но использование SWT только для этого может быть неоптимальным.

asalamon74 29.11.2008 00:26

Вы можете использовать способ по умолчанию ОС, чтобы открыть его для вас.

  • Windows: "cmd / c имя файла"
  • Linux с gnome "gnome-open имя файла"
  • Linux с Kde ??
  • OSx "открыть имя файла"
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));
  }

Вы также можете использовать полиморфизм с этим. Таким образом, вы можете добавить гибкости реализации. Тогда вы можете избежать еще одной цепочки if / elseif / else для следующей операции.

OscarRyz 28.11.2008 20:37

Вы должны использовать xdg-open вместо gnome-open или kfmclient или чего-то еще, чтобы он лучше работал в xfce или других средах.

Josh Lee 29.11.2008 03:23

JDIC - это библиотека, которая обеспечивает функциональные возможности настольного компьютера в Java 1.5.

Эта библиотека, кажется, решает проблему. Я не понимаю, почему люди проголосовали за изобретение велосипеда ...

Lucas Pottersky 23.04.2010 19:28
Ответ принят как подходящий

+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 и требуется изменение, вы можете забыть обновить одну из них или скопировать / при вставке вы можете забыть изменить команду для выполнения)

@KrzysztofCichocki, вы не можете объяснить, почему вы думаете, что это не решение, таким образом, люди, читающие этот ответ, могут оценить, использовать его или нет.

OscarRyz 07.12.2015 20:08

Вы не показали никакого кода, который действительно работает и открывает браузер по умолчанию для java 1.5, просто какой-то скелет для него без какой-либо полезной реализации, поэтому это не решение.

Krzysztof Cichocki 07.12.2015 21:49

Мы помещаем команду снаружи где-то в файле конфигурации.

Ваш «JAR и исходный код» будут «кроссплатформенными», а ваше развертывание - нет.

Вы также можете сделать что-то вроде этот ответ. Вы можете поместить имя класса фабричного класса реализации "Deskop" в установочный файл. (может быть путеводителем или пружиной, если хотите)

Просто как дополнение: вместо gnome-open используйте xdg-open. Это часть XdgUtils, которые, в свою очередь, являются частью пакета поддержки LSB Desktop (начиная с 3.2).

Вы можете (должны) по-прежнему использовать gnome-open в качестве запасного варианта, но xdg-open также будет работать на рабочих столах, отличных от GNOME.

Отличное дополнение. Я не знал об этом пакете.

asalamon74 29.11.2008 12:26

Другой ответ (by boutta) предлагает использовать SWT. Я бы не рекомендовал ссылаться на библиотеку только для этой цели, но если вы ее уже используете, просто выполните:

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

Обратите внимание, что этот метод будет работать (и вернуть true), если объект Display уже был создан (например, путем создания Shell). Также обратите внимание, что он должен выполняться в основном потоке; например.:

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

В приведенном выше примере я запустил URL-адрес, но запуск файлов работает точно так же.

Другие вопросы по теме