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.
2 Answers
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;
}
}
1 Comment
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
tcp,http,ssh, etc.scpcommand to copy your file. You can follow the answer by @Christopher Maggiulli below by usingpscpto do that or you can find any other tool of your choice tosecure copyto Unix server.