Hi!

How could I open a file saved on FTP Server? I'm using org.apache.commons.net.ftp.FTPClient to save/delete files. There are only 5 types of files: doc, docx, xls, xlsx, pdf. If I select a pdf file, then it must be opened in Adobe Acrobat, etc. So, what is the best approach for solving this task?

Thanks!

For instance, the code below allows opening files on local machine. But, as I understand, it cannot be used for FTP Server. Also, I would like to find a method that will work not only in Windows.

try
            {
                Process p = Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + directoryPath + fileName);
                p.waitFor();

            } catch (Exception e)
            {
                  System.out.println("Error" + e );
            }

Retrieve the file locally and use Desktop.open() would probably be the easiest option.

Thanks! Now it works (see the code below). But is it possible to delete the viewed file when it is closed? So, I must somehow detect that it is closed. How could I do this?

private void openFile(String fileName) {
        FTPClient client = new FTPClient();
        FileOutputStream fos = null;
 
        try {
            client.connect(this.url);
            client.login(this.login,this.password);

            DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)SystClasses.TreeEditTest.tree1.getLastSelectedPathComponent(); 
            String directoryPath = new String();
            Object elements[] = selectedNode.getPath();
      
            for (int i = 0, n = elements.length; i < n; i++) {
                directoryPath = directoryPath + elements[i] + "\\";
            }
            
            fos = new FileOutputStream(fileName);

            client.retrieveFile(directoryPath + fileName, fos);
            
            File file = new File(fileName);
            try {
                Desktop.getDesktop().open(file);
            }
            catch (IOException ioe) {
                ioe.printStackTrace();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                client.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  }

I'm trying to use file.deleteOnExit():

...
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                    file.deleteOnExit();
                }
                client.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
...

Let's say the *.txt file is opened in Notepad. When I close the Notepad (in fact, the file), the file is not deleted from local machine... Why?

Well, the file was actually deleted when I closed my JAVA application. It seems that file.deleteOnExit() did its job.

But how could I delete the file exactly after closing Notepad (or any other lookup program)?

But how could I delete the file exactly after closing Notepad (or any other lookup program)?

In that case, you need to ditch the Desktop class and look into the Process/ProcessBuilder classes and the `waitFor()' method. Some sample code:

public class ProcessTest {

    public static void main(final String[] args) throws Exception {
        final ProcessBuilder pb = new ProcessBuilder("notepad", args[0]);
        final Process p = pb.start();
        System.out.println("Starting wait");
        System.out.println("Wait status: " + p.waitFor());
        System.out.println("Wait complete");
        new File(args[0]).delete();
    }

}

Great! It works. But if I have .doc, .pdf, .xls files, then how could I update this code? Should I use IF...THEN statement to indicate a file type?

It's a bit complicated since interacting with external applications which can differ based on the OS/file types isn't exactly Java's forte.

Hardcoding application name/paths works but has a couple of drawbacks:

  • Users would typically want the file to be opened with the application with which they have associated the file type. For e.g. computer savvy users normally use other text editing tools like notepad++, vim etc. for editing files instead of notepad.
  • The application selection IF ELSE checks need to go down one more level to accommodate different Operating Systems. E.g. windows, linux etc.

You'd require a library which abstracts the file association lookup, something like JDIC. This library isn't exactly user friendly or feature complete but gives you the basic file association lookup functionality. It might be a bit of overhead to include this big a JAR just for file association but the choice is yours. A sample snippet:

package home.projects.misc.classloader;

import org.jdesktop.jdic.filetypes.Action;
import org.jdesktop.jdic.filetypes.Association;
import org.jdesktop.jdic.filetypes.AssociationService;

public class ProcessTest {

    public static void main(final String[] args) throws Exception {
        AssociationService s = new AssociationService();
        Association o = s.getFileExtensionAssociation(".doc");
        Action appAction = o.getActionByVerb("edit");
        String appName = appAction.getCommand().split("\" ")[0].replaceAll("\"", "");
        final ProcessBuilder pb = new ProcessBuilder(appName, args[0]);
        final Process p = pb.start();
        System.out.println("Starting wait");
        System.out.println("Wait status: " + p.waitFor());
        System.out.println("Wait complete");
        new File(args[0]).delete();
    }

    public static void p(Object s) {
        System.out.println(s);
    }
    
}

Play around with the API to get it working as per your specific need.

Ok, thank you very much!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.