sshj icon indicating copy to clipboard operation
sshj copied to clipboard

SFTPClient get methods do not allow to append the whole source to the destination

Open jcourelscj opened this issue 1 year ago • 0 comments

What I want to do

Using the SFTPClient class, I would like to be able to download a source file from the SFTP server and append all of its content to the destination file.

What the library allows to do

Using SFTPClient get() methods either :

  • Download the source and overwrite the destination
  • Download the source and append it to the destination with the specified byteOffset. But if byteOffset is set to 0, the first case is occurring instead.

I think the issue comes from the SFTPFileTransfer downloadFile method :

final OutputStream os = adjusted.getOutputStream(byteOffset != 0);

My workaround

For now, I am using the code below to perform what I want to do :

private CustomSSHClient mSshClient;
private SFTPClient mSftpClient;
...
        try {
            SFTPEngine engine = mSftpClient.getSFTPEngine();
            SFTPFileTransfer fileTransfer = mSftpClient.getFileTransfer();

            RemoteResourceInfo remoteResourceInfo = new RemoteResourceInfo(
                    engine.getPathHelper().getComponents(srcFilePath),
                    engine.stat(srcFilePath)
            );
            
            final LocalDestFile adjusted = new FileSystemFile(desFilePath).getTargetFile(remoteResourceInfo.getName());
            final RemoteFile rf = engine.open(remoteResourceInfo.getPath());
            
            final RemoteFile.ReadAheadRemoteFileInputStream rfis = rf.new ReadAheadRemoteFileInputStream(16, 0);
            final OutputStream os = adjusted.getOutputStream(true);
            
            new StreamCopier(rfis, os, mSshClient.getLoggerFactory())
                            .bufSize(engine.getSubsystem().getLocalMaxPacketSize())
                            .keepFlushing(false)
                            .listener(fileTransfer.getTransferListener().file(remoteResourceInfo.getName(), remoteResourceInfo.getAttributes().getSize()))
                            .copy();
            
            rfis.close();
            os.close();
            rf.close();
        } catch (IOException exception) {
            
        }
...
    public class CustomSSHClient extends SSHClient{
        public LoggerFactory getLoggerFactory(){
            return loggerFactory;
        }
    }

jcourelscj avatar Mar 01 '23 09:03 jcourelscj