In Transferring Files, we covered how to use the high-level API of SshClient to perform basic upload and download of files. To provide a more rich SFTP experience, the Maverick Synergy API provides the SftpClient.
Those familiar with the Maverick Legacy Client API will find the SftpClient similar to the SftpClient class that previously implemented SFTP.
You can use the following template in your application to connect, authenticate and start the SftpClientTask.
try (SshClient ssh = SshClientBuilder.create()
.withHostname("localhost")
.withPort(2222)
.withUsername("root")
.withPassword("xxxx")
.build()) {
SftpClient sftp = SftpClientBuilder.create()
.withClient(ssh)
.build();
}
To upload a file from the current file system, you can:
sftp.put("tmp.dmg");
You can also pass OutputStream to receive the file content without going to the local file system.
ByteArrayOutputStream out = new ByteArrayOutputStream();
sftp.get("tmp.dmg", out);
Or get an InputStream of the file content to process.
InputStream in = sftp.getInputStream("tmp.dmg");
Similarly, you can pass an InputStream to write out data from your application held in an InputStream.
InputStream in = ....
sftp.put(in, "tmp.dmg");
Or get an OutputStream to write content to the remote system.
OutputStream out = sftp.getOutputStream("tmp.dmg");
The methods detailed so far only deal with a single file at a time. For example, we can download all files with a specific pattern using the getFiles method. This returns an array of SftpFile objects that have been transferred.
SftpFile[] files = sftp.getFiles("*rfc*.txt");
We can also do the same and putFiles
sftp.putFiles("*rfc&.txt");
Matching is performed using Glob syntax by default. You can use a Perl Syntax for regular expressions also. To do this you will need to configure the pattern matcher first.
sftp.setRegularExpressionSyntax(SftpClientTask.Perl5Syntax);
You can change the user’s local directory by calling the following:
sftp.lcd("/tmp");
Or change the remote directory using:
sftp.cd("/opt");
To get the remote working directory
sftp.pwd();
To get the local working directory
sftp.lpwd();
There are several methods for manipulating the permissions on the remote file system. Remember that Unix permissions are normally stated in an octal numbering system rather than decimal, so any value passed should be preceded by zero to indicate this to the JVM.
sftp.chmod(PosixPermissionsBuilder.create()
.fromBitmask(0644)
.build(), "tmp.dmg");
You can change the owner or group of the file
sftp.chown("501", "tmp.dmg");
sftp.chgrp("501", "tmp.dmg");
In SFTP version 3 or below, the UID/GID expected is normally the numerical ID and not the user or group name. Version 4 or above support names. The methods take a string to allow both to be passed.
By default, a umask is not applied to files and folders created remotely. If you do not want the server to decide the permissions, you should apply a umask setting. You can change the umask value using:
sftp.umask(0022);
This will apply the default permissions of 0666 ^ 0022 for new files and 0777 ^ 0022 for new folders.
You can get the current SftpFileAttributes of a file using a stat command.
SftpFileAttributes attrs = sftp.stat("tmp.dmg")
Or the attributes of a link
SftpFileAttributes attrs = sftp.statLink("tmp.dmg")
If you want to change the attributes, get them using the above stat call and make modifications, then call
sftp.setAttributes("tmp.dmg", attrs);
To get the target of a symbolic link
sftp.getSymbolicLinkTarget("linkpath");
To move a file you rename it.
sftp.rename("tmp.dmg", "new.dmg");
To delete a file, use.
sftp.rm("tmp.dmg");