Search code examples
javaxmlsftpvfs

How to save a FileObject from SFTP as local file?


I want to write a java program to test an interface, that communicates via xml-files over SFTP. The idea of the interface is that one side uploads an xml-file, then the other side processes it, deletes it and uploads another xml-file as acknowledgement.

What my program is supposed to do, is upload an xml-file, wait for it to vanish, wait for the response, save it as local file and then check the correctness of the response. I implemented this using org.apache.commons.vfs2 and FileObjects and can successfully upload an xml-file, wait for it to vanish and check the existence of the acknowledgement-file. But as soon as i try to parse the file as document using the code

    FileObject ackFileObject = VFS.getManager().resolveFile("sftp://[email protected]/SFTPfolder/file.xml");
    File ackFile = new File(ackFileObject.getName().getPath());
    DocumentBuilderFactory documentBuilderFactory = 
    DocumentBuilderFactory.newInstance();
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    Document document = documentBuilder.parse(ackFile);

I get a FileNotFoundException, because the documentBuilder tries to read the file from "C:/SFTPfolder/" instead of reading it from the project path. Also "new File(ackFileObject.getName().getPath());" doesn't create a new File.

Is there an easy solution to fix this? How can I save a FileObject I get from VFS.getManager().resolveFile() as local File, so I can parse it as document?


Solution

  • Use copyFrom() method. You need to define your remote and your local paths first:

    You have already defined your remote file:

        FileObject ackFileObject = VFS.getManager()
                       .resolveFile("sftp://[email protected]/SFTPfolder/file.xml");
    

    Now define the path you want to copy your remote path to:

        FileObject ackFileObjectLocal = VFS.getManager()
                      .resolveFile(localFilePath);
    

    Where you have to set up localFilePath variable before or set it as a constant.

    Then use: ackFileObjectLocal.copyFrom(ackFileObject, Selectors.SELECT_SELF);

    So now you have your file downloaded and can wrap it with File object to proceed with your processing.