0

How do I create a Java script that copies a file to a Unix Server? I need the process to be automated, as it's the need of my application that file should be automatically copied to the server with code.

4
  • What is the physical architecture of your setup? Windows machine and a Unix server? Does Unix server expose any kind of interface to do that kind of copy thing? Like any form of communication channel e.g. tcp, http, ssh, etc. Commented Jun 16, 2017 at 4:26
  • I am able to make my connection with JSch library to Unix server. That give me functionality to execute the command on server. But I use vi through code then it's response is not proper format that I can modify for our use. that's why I make the file in local machine and want to transfer to Unix server. Commented Jun 16, 2017 at 4:30
  • @Azeem I am using ssh connection Commented Jun 16, 2017 at 4:31
  • Then, you can simply use scp command to copy your file. You can follow the answer by @Christopher Maggiulli below by using pscp to do that or you can find any other tool of your choice to secure copy to Unix server. Commented Jun 16, 2017 at 4:33

2 Answers 2

4

This is the correct approach with JSch external java library.

  import com.jcraft.jsch.*;
  import java.io.*;

    public class ScpTo{
    public static void main(String[] arg){
      FileInputStream fis=null;
       try{
       String lfile="file.txt";
        String user="username";
        String host="host";
     String rfile="file1.txt";

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

     java.util.Properties config = new java.util.Properties(); 
     config.put("StrictHostKeyChecking", "no");
     session.setPassword("******");
      session.setConfig(config);
       session.connect();

  boolean ptimestamp = false;
  // exec 'scp -t rfile' remotely
  String command="scp " + (ptimestamp ? "-p" :"") +" -t "+rfile;
  Channel channel=session.openChannel("exec");
  ((ChannelExec)channel).setCommand(command);

  // get I/O streams for remote scp
  OutputStream out=channel.getOutputStream();
  InputStream in=channel.getInputStream();

  channel.connect();

  if(checkAck(in)!=0){
System.exit(0);
  }

  File _lfile = new File(lfile);

  if(ptimestamp){
    command="T "+(_lfile.lastModified()/1000)+" 0";
    // The access time should be sent here,
    // but it is not accessible with JavaAPI ;-<
    command+=(" "+(_lfile.lastModified()/1000)+" 0\n"); 
    out.write(command.getBytes()); out.flush();
    if(checkAck(in)!=0){
  System.exit(0);
    }
  }

  // send "C0644 filesize filename", where filename should not include '/'
  long filesize=_lfile.length();
  command="C0644 "+filesize+" ";
  if(lfile.lastIndexOf('/')>0){
    command+=lfile.substring(lfile.lastIndexOf('/')+1);
  }
  else{
    command+=lfile;
  }
  command+="\n";
  out.write(command.getBytes()); out.flush();
  if(checkAck(in)!=0){
System.exit(0);
  }

  // send a content of lfile
  fis=new FileInputStream(lfile);
  byte[] buf=new byte[1024];
  while(true){
    int len=fis.read(buf, 0, buf.length);
if(len<=0) break;
    out.write(buf, 0, len); //out.flush();
  }
  fis.close();
  fis=null;
  // send '\0'
  buf[0]=0; out.write(buf, 0, 1); out.flush();
  if(checkAck(in)!=0){
System.exit(0);
  }
  out.close();
  System.out.print("Transfer done.");

  channel.disconnect();
  session.disconnect();

  System.exit(0);
}
catch(Exception e){
  System.out.println(e);
  try{if(fis!=null)fis.close();}catch(Exception ee){}
}
}

static int checkAck(InputStream in) throws IOException{
int b=in.read();
// b may be 0 for success,
//          1 for error,
//          2 for fatal error,
//          -1
if(b==0) return b;
if(b==-1) return b;

if(b==1 || b==2){
  StringBuffer sb=new StringBuffer();
  int c;
  do {
c=in.read();
sb.append((char)c);
  }
  while(c!='\n');
  if(b==1){ // error
System.out.print(sb.toString());
  }
  if(b==2){ // fatal error
System.out.print(sb.toString());
  }
}
return b;
 }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Hello , thanks for sharing the code it works right , can you tell what to do if we want to include RSA key for connecting to external systems :)
2

Example

You can download pscp from PuTTY. Add the pscp.exe to your path. You can then run something like the following

Runtime.getRuntime().exec("pscp.exe C:\Users\usr\Downloads>pscp -r -P 22 "directory123" [email protected]:/tmp");

Explanation

PSCP is a command line application. This means that you cannot just double-click on its icon to run it and instead you have to bring up a console window. With Windows 95, 98, and ME, this is called an ‘MS-DOS Prompt’ and with Windows NT, 2000, and XP, and beyond it is called a ‘Command Prompt’. It should be available from the Programs section of your Start Menu.

To start PSCP it will need either to be on your PATH or in your current directory. To add the directory containing PSCP to your PATH environment variable, type into the console window:

set PATH=C:\path\to\putty\directory;%PATH%

Once you do that you can now access it from your Java application and from anywhere in your command prompt / shell by typing pscp.exe. In other words if, after setting your pscp directory as a path location, you can open the command prompt and call the pscp.exe program while you are in any directory. The code I posted is pretty much just a way to run shell commands in your java program.

pscp.exe C:\Users\usr\Downloads>pscp -r -P 22 "directory123" [email protected]:/tmp

is the command prompt / shell command and

Runtime.getRuntime().exec("....");

is the way to run shell commands in Java. You will need to change the directories in the command accordingly

2 Comments

Can you explain little more
Did the explanation suffice?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.