使用SFTP从本地文件夹将文件上载到远程文件夹

时间:2016-05-12 08:55:04

标签: java file-upload sftp

我试图将文件从本地文件夹上传到远程文件夹。但是我收到错误,我不知道我在哪里弄错了。我希望有人帮助找到解决方案。感谢。

以下代码:

public static void main(String[] args) {
        String server = "www.xyz.com";
        int port = 22;
        String user = "user";
        String pass = "admin@12";

        FTPClient ftpClient = new FTPClient();
        try {

            ftpClient.connect(server, port);
            System.out.println("1");
            ftpClient.login(user, pass);
            System.out.println("2");
            ftpClient.enterLocalPassiveMode();

            System.out.println("3");

            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            System.out.println("4");

            // APPROACH #1: uploads first file using an InputStream
            File firstLocalFile = new File("D:/UploadServlet.java");

            String firstRemoteFile = "Projects.zip";
            InputStream inputStream = new FileInputStream(firstLocalFile);

            System.out.println("Start uploading first file");
            boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
            inputStream.close();
            if (done) {
                System.out.println("The first file is uploaded successfully.");
            }



        } catch (IOException ex) {
            System.out.println("Error: " + ex.getMessage());
            ex.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.logout();
                    ftpClient.disconnect();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

每当我执行代码时都会收到以下错误。

Error: Could not parse response code.
Server Reply: SSH-2.0-OpenSSH_4.3
org.apache.commons.net.MalformedServerReplyException: Could not parse response code.
Server Reply: SSH-2.0-OpenSSH_4.3
    at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:284)
    at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:335)
    at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:550)
    at org.apache.commons.net.SocketClient.connect(SocketClient.java:163)
    at FTPUploadFileDemo.main(FTPUploadFileDemo.java:26)
org.apache.commons.net.MalformedServerReplyException: Could not parse response code.
Server Reply: Protocol mismatch.
    at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:284)
    at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:460)
    at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:520)
    at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:569)
    at org.apache.commons.net.ftp.FTP.quit(FTP.java:781)
    at org.apache.commons.net.ftp.FTPClient.logout(FTPClient.java:706)
    at FTPUploadFileDemo.main(FTPUploadFileDemo.java:58)

3 个答案:

答案 0 :(得分:0)

您确定使用有效的ftp服务器和端口吗?

String server = "www.xyz.com";
int port = 22;

您的示例中的服务器返回“SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1”

telnet www.xyz.com 22
SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1

答案 1 :(得分:0)

对于SFTP(基于SSH的FTP),您无法使用库Apache Commons Net,因为它支持FTPS(基于SSL的FTP)。

但您可以使用例如Jsch SSH2(BSD样式许可证)的纯Java实现或任何商业SFTP库。

Jsch的SFTP示例在http://www.jcraft.com/jsch/examples/Sftp.java提供。

答案 2 :(得分:0)

以下SFTP实用程序提供了上载,存在,下载,移动和删除操作的示例。我在我的几个项目中使用了这个。以下代码仅使用来自Apache Commons VFS库的api调用。

请确保将以下JAR放入项目的构建路径中:

  1. 共享记录-1.1.3.jar
  2. 公地vfs2-2.0.jar
  3. hamcrest核-1.3.jar
  4. jsch-0.1.50.jar
  5. 任何其他兼容版本也可以。

    import java.io.File;
    
    import org.apache.commons.vfs2.FileObject;
    import org.apache.commons.vfs2.FileSystemException;
    import org.apache.commons.vfs2.FileSystemOptions;
    import org.apache.commons.vfs2.Selectors;
    import org.apache.commons.vfs2.impl.StandardFileSystemManager;
    import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
    
    /**
     * The class SFTPUtil containing uploading, downloading, checking if file exists
     * and deleting functionality using Apache Commons VFS (Virtual File System)
     * Library
     * 
     * @author Ashok
     * 
     */
    public class SFTPUtility {
    
        public static void main(String[] args) {
            String hostName = "PutYourHostNameHere";
            String username = "PutYourUserNameForHostHere";
            String password = "PutYourPasswordForHostHere";
    
            String localFilePath = "C:\\FakePath\\FakeFile.txt";
            String remoteFilePath = "/FakeRemotePath/FakeRemoteFile.txt";       
            String remoteTempFilePath = "/FakeRemoteTempPath/FakeRemoteTempFile.txt";
    
            upload(hostName, username, password, localFilePath, remoteFilePath);
            exist(hostName, username, password, remoteFilePath);
            download(hostName, username, password, localFilePath,remoteFilePath);
            move(hostName, username, password, remoteFilePath, remoteTempFilePath);
            delete(hostName, username, password, remoteFilePath);
        }
    
        /**
         * Method to upload a file in Remote server
         * 
         * @param hostName
         *            HostName of the server
         * @param username
         *            UserName to login
         * @param password
         *            Password to login
         * @param localFilePath
         *            LocalFilePath. Should contain the entire local file path -
         *            Directory and Filename with \\ as separator
         * @param remoteFilePath
         *            remoteFilePath. Should contain the entire remote file path -
         *            Directory and Filename with / as separator
         */
        public static void upload(String hostName, String username, String password, String localFilePath, String remoteFilePath) {
    
            File file = new File(localFilePath);
            if (!file.exists())
                throw new RuntimeException("Error. Local file not found");
    
            StandardFileSystemManager manager = new StandardFileSystemManager();
    
            try {
                manager.init();
    
                // Create local file object
                FileObject localFile = manager.resolveFile(file.getAbsolutePath());
    
                // Create remote file object
                FileObject remoteFile = manager.resolveFile(createConnectionString(hostName, username, password, remoteFilePath), createDefaultOptions());
                /*
                 * use createDefaultOptions() in place of fsOptions for all default
                 * options - Ashok.
                 */
    
                // Copy local file to sftp server
                remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
    
                System.out.println("File upload success");
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                manager.close();
            }
        }
    
        public static boolean move(String hostName, String username, String password, String remoteSrcFilePath, String remoteDestFilePath){
            StandardFileSystemManager manager = new StandardFileSystemManager();
    
            try {
                manager.init();
    
                // Create remote object
                FileObject remoteFile = manager.resolveFile(createConnectionString(hostName, username, password, remoteSrcFilePath), createDefaultOptions());
                FileObject remoteDestFile = manager.resolveFile(createConnectionString(hostName, username, password, remoteDestFilePath), createDefaultOptions());
    
                if (remoteFile.exists()) {
                    remoteFile.moveTo(remoteDestFile);;
                    System.out.println("Move remote file success");
                    return true;
                }
                else{
                    System.out.println("Source file doesn't exist");
                    return false;
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                manager.close();
            }
        }
    
        /**
         * Method to download the file from remote server location
         * 
         * @param hostName
         *            HostName of the server
         * @param username
         *            UserName to login
         * @param password
         *            Password to login
         * @param localFilePath
         *            LocalFilePath. Should contain the entire local file path -
         *            Directory and Filename with \\ as separator
         * @param remoteFilePath
         *            remoteFilePath. Should contain the entire remote file path -
         *            Directory and Filename with / as separator
         */
        public static void download(String hostName, String username, String password, String localFilePath, String remoteFilePath) {
    
            StandardFileSystemManager manager = new StandardFileSystemManager();
    
            try {
                manager.init();
    
                // Append _downlaod_from_sftp to the given file name.
                //String downloadFilePath = localFilePath.substring(0, localFilePath.lastIndexOf(".")) + "_downlaod_from_sftp" + localFilePath.substring(localFilePath.lastIndexOf("."), localFilePath.length());
    
                // Create local file object. Change location if necessary for new downloadFilePath
                FileObject localFile = manager.resolveFile(localFilePath);
    
                // Create remote file object
                FileObject remoteFile = manager.resolveFile(createConnectionString(hostName, username, password, remoteFilePath), createDefaultOptions());
    
                // Copy local file to sftp server
                localFile.copyFrom(remoteFile, Selectors.SELECT_SELF);
    
                System.out.println("File download success");
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                manager.close();
            }
        }
    
        /**
         * Method to delete the specified file from the remote system
         * 
         * @param hostName
         *            HostName of the server
         * @param username
         *            UserName to login
         * @param password
         *            Password to login
         * @param localFilePath
         *            LocalFilePath. Should contain the entire local file path -
         *            Directory and Filename with \\ as separator
         * @param remoteFilePath
         *            remoteFilePath. Should contain the entire remote file path -
         *            Directory and Filename with / as separator
         */
        public static void delete(String hostName, String username, String password, String remoteFilePath) {
            StandardFileSystemManager manager = new StandardFileSystemManager();
    
            try {
                manager.init();
    
                // Create remote object
                FileObject remoteFile = manager.resolveFile(createConnectionString(hostName, username, password, remoteFilePath), createDefaultOptions());
    
                if (remoteFile.exists()) {
                    remoteFile.delete();
                    System.out.println("Delete remote file success");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                manager.close();
            }
        }
    
        // Check remote file is exist function:
        /**
         * Method to check if the remote file exists in the specified remote
         * location
         * 
         * @param hostName
         *            HostName of the server
         * @param username
         *            UserName to login
         * @param password
         *            Password to login
         * @param remoteFilePath
         *            remoteFilePath. Should contain the entire remote file path -
         *            Directory and Filename with / as separator
         * @return Returns if the file exists in the specified remote location
         */
        public static boolean exist(String hostName, String username, String password, String remoteFilePath) {
            StandardFileSystemManager manager = new StandardFileSystemManager();
    
            try {
                manager.init();
    
                // Create remote object
                FileObject remoteFile = manager.resolveFile(createConnectionString(hostName, username, password, remoteFilePath), createDefaultOptions());
    
                System.out.println("File exist: " + remoteFile.exists());
    
                return remoteFile.exists();
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                manager.close();
            }
        }
    
        /**
         * Generates SFTP URL connection String
         * 
         * @param hostName
         *            HostName of the server
         * @param username
         *            UserName to login
         * @param password
         *            Password to login
         * @param remoteFilePath
         *            remoteFilePath. Should contain the entire remote file path -
         *            Directory and Filename with / as separator
         * @return concatenated SFTP URL string
         */
        public static String createConnectionString(String hostName, String username, String password, String remoteFilePath) {
            return "sftp://" + username + ":" + password + "@" + hostName + "/" + remoteFilePath;
        }
    
        /**
         * Method to setup default SFTP config
         * 
         * @return the FileSystemOptions object containing the specified
         *         configuration options
         * @throws FileSystemException
         */
        public static FileSystemOptions createDefaultOptions() throws FileSystemException {
            // Create SFTP options
            FileSystemOptions opts = new FileSystemOptions();
    
            // SSH Key checking
            SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
    
            /*
             * Using the following line will cause VFS to choose File System's Root
             * as VFS's root. If I wanted to use User's home as VFS's root then set
             * 2nd method parameter to "true"
             */
            // Root directory set to user home
            SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, false);
    
            // Timeout is count by Milliseconds
            SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
    
            return opts;
        }
    }