Cross-platform way to open a file using Java 1.5

后端 未结 8 784

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 J

相关标签:
8条回答
  • 2020-12-16 18:24

    +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)

    0 讨论(0)
  • 2020-12-16 18:27

    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.

    0 讨论(0)
  • 2020-12-16 18:32

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

    0 讨论(0)
  • 2020-12-16 18:33

    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"
    0 讨论(0)
  • 2020-12-16 18:35

    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.

    0 讨论(0)
  • 2020-12-16 18:44

    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.

    0 讨论(0)
提交回复
热议问题