使用Java将文件从Unix传输到Windows

10

我想使用Java将Unix系统中的文件传输到我的Windows本地系统上。对于这个概念,我还很陌生。有什么想法可以实现吗?哪个是最适合此任务的Java API?


你能解释一下为什么你特别想使用Java吗?Samba或SFTP是可用的、随时安装的选项,已经可以实现这个功能了。 - chrylis -cautiouslyoptimistic-
4个回答

9
如果Unix机器支持SFTP,JSch是一个选择。您可以根据需要调整以下代码:
private static final String USER_PROMPT = "Enter username@hostname:port";
private static final boolean USE_GUI = true;

public static void main(final String[] arg) {
  Session session = null;
  ChannelSftp channelSftp = null;
  try {
    final JSch jsch = new JSch();

    final String defaultInput = System.getProperty("user.name") + "@localhost:22";
    String input = (USE_GUI) ? JOptionPane.showInputDialog(USER_PROMPT, defaultInput) : System.console().readLine("%s (%s): ", USER_PROMPT, defaultInput);
    if (input == null || input.trim().length() == 0) {
      input = defaultInput;
    }
    final int indexOfAt = input.indexOf('@');
    final int indexOfColon = input.indexOf(':');
    final String user = input.substring(0, indexOfAt);
    final String host = input.substring(indexOfAt + 1, indexOfColon);
    final int port = Integer.parseInt(input.substring(indexOfColon + 1));

    jsch.setKnownHosts("/path/to/known_hosts");
    // if you have set up authorized_keys on the server, using that identitiy
    // with the code on the next line allows for password-free, trusted connections
    // jsch.addIdentity("/path/to/id_rsa", "id_rsa_password");

    session = jsch.getSession(user, host, 22);

    final UserInfo ui = new MyUserInfo();
    session.setUserInfo(ui);
    session.connect();
    channelSftp = (ChannelSftp) session.openChannel("sftp");
    channelSftp.connect();
    channelSftp.get("/remotepath/remotefile.txt", "/localpath/localfile.txt");
  } finally {
    if (channelSftp != null) {
      channelSftp.exit();
    }
    if (session != null) {
      session.disconnect();
    } 
  }
}

public static class MyUserInfo implements UserInfo {
  private String password;

  @Override
  public String getPassword() {
    return password;
  }

  @Override
  public boolean promptYesNo(final String str) {
    final Object[] options = {"yes", "no"};
    final boolean yesNo = (USE_GUI) ? JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]) == 0 : System.console().readLine("Enter y or n: ").equals("y");
    return yesNo;
  }

  @Override
  public String getPassphrase() {
    return null;
  }

  @Override
  public boolean promptPassphrase(final String message) {
    return true;
  }

  @Override
  public boolean promptPassword(final String message) {
    if (!USE_GUI) {
      password = new String(System.console().readPassword("Password: "));
      return true;
    } else {
      final JTextField passwordField = new JPasswordField(20);
      final Object[] ob = {passwordField};
      final int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION);
      if (result == JOptionPane.OK_OPTION) {
        password = passwordField.getText();
        return true;
      } else {
        return false;
      }
    }
  }

  @Override
  public void showMessage(final String message) {
    if (!USE_GUI) {
      System.console().printf(message);
    } else {
      JOptionPane.showMessageDialog(null, message);
    }
  }
}

非常巧妙和优雅的方法。 - Nitin Mahesh
channelSftp.get("/remotepath/remotefile.txt", "/localpath/localfile.txt"); 特别有帮助。 - parishodak
我尝试将相同的代码放入Windows机器中以远程访问Linux机器,但是出现了“算法协商失败”的错误。 - Issac Balaji

4

我发现JSch非常实用和直接。以下是一段代码片段,用于将给定文件夹中的所有.txt文件放在SFTP服务器上。

public static void sftpConnection() {

    // Object Declaration.
    JSch jsch = new JSch();
    Session session = null;
    Channel channel = null;

    // Variable Declaration.
    String user = "foo";
    String host = "10.9.8.7";
    Integer port = 22;
    String password = "test123";
    String watchFolder = "\\localhost\textfiles";
    String outputDir = "/remote/textFolder/";
    String filemask = "*.txt";


   try {
        session = jsch.getSession(user, host, port);

        /*
         * StrictHostKeyChecking Indicates what to do if the server's host 
         * key changed or the server is unknown. One of yes (refuse connection), 
         * ask (ask the user whether to add/change the key) and no 
         * (always insert the new key).
         */
        session.setConfig("StrictHostKeyChecking", "no");
        session.setPassword(password);

        session.connect();

        channel = session.openChannel("sftp");
        channel.connect();
        ChannelSftp sftpChannel = (ChannelSftp)channel;

        // Go through watch folder looking for files.
        File[] files = findFile(watchFolder, filemask);
        for(File file : files) {
            // Upload file.
            putFile(file, sftpChannel, outputDir);            
        }                 
    } finally {
        sftpChannel.exit();
        session.disconnect();
    }
}

public static void putFile(File file, ChannelSftp sftpChannel, String outputDir) {

    FileInputStream fis = null;

    try {
        // Change to output directory.
        sftpChannel.cd(outputDir);

        // Upload file.

        fis = new FileInputStream(file);
        sftpChannel.put(fis, file.getName());
        fis.close();

    } catch{}
}

public static File[] findFile(String dirName, final String mask) {
    File dir = new File(dirName);

    return dir.listFiles(new FilenameFilter() {
        public boolean accept(File dir, String filename)
            { return filename.endsWith(mask); }
    } );
}

2

我脑海里首先想到的是FTP。


1
但FTP是不安全的,我认为我们最好使用SFTP。 - user1585111

2

谢谢,我得到了一些好的信息。有没有Java API可以使这些事情变得更简单? - user1585111
@user1585111 Java API可用于套接字通信,并得到广泛应用。请查看此链接:http://download.oracle.com/javase/tutorial/networking/sockets/ - Juned Ahsan
JSch能帮助我完成这个任务吗? - user1585111
@user1585111 可以的。 - Juned Ahsan
我可以使用jsch连接到启用sftp的Unix系统,但之后无法在该系统上执行Unix命令。 - user1585111

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接