Create ZIP Stream Before Uploading Files to SFTP

This post is related to SFTP Client Using SSHJ, we are going to Create ZIP Stream Before Uploading Files to SFTP.  ZIP Stream means we are not going to save zipped files to local storage / disk. 

With SSHJ, we can upload files from the local path and from LocalSourceFile, with LocalSourceFile we can set the InputStream to be uploaded.

We are going to implement LocalSourceFile by extending InMemorySourceFile, let's create class namedZipStreamSourceFile

  
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import net.schmizz.sshj.xfer.InMemorySourceFile;
public class ZipStreamSourceFile extends InMemorySourceFile {
	private String name;
	private ByteArrayOutputStream bos;
	
	public ZipStreamSourceFile(File localFile) throws Exception {
		super();
		if (localFile.exists()) {
			this.name = localFile.getName();
			bos = new ByteArrayOutputStream();
			try (FileInputStream fin = new FileInputStream(localFile);
					ZipOutputStream zos = new ZipOutputStream(bos))
			{
				ZipEntry zipEntry = new ZipEntry(localFile.getName());
				zos.putNextEntry(zipEntry);
				for (int c = fin.read(); c != -1; c = fin.read()) {
			          zos.write(c);
			    }
			}
		} else {
			throw new Exception("File Not Found");
		}
	}
	@Override
	public String getName() {
		try {
			byte[] hash = MessageDigest.getInstance("MD5").digest(bos.toByteArray());
			String checksum = new BigInteger(1, hash).toString(16);
			return name+"-"+checksum+SftpClient.COMPRESS_EXT;
		} catch (Exception e) {
		}
		return null;
	}
	@Override
	public long getLength() {
		return Long.valueOf(String.valueOf(bos.size()));
	}
	@Override
	public InputStream getInputStream() throws IOException {	
		return new ByteArrayInputStream(bos.toByteArray());
	}
}
  

By extending InMemorySourceFile, all we need to do is implement getName, getLength, and getInputStream methods. But, before that we are going to create the Constructor with File param. This constructor will check whether the file exists or not, if the file exists, then we are going to zip the file.

For the getName method, we are going to set the file name with checksum of the zipped file, then the getLength we are going to set the length of the zipped file, and for the getInputStream method, we are going to set the ByteArrayInputStream of the zipped file.

Finally, we are going to modify the uploadFile method with additional parameters to indicate that we need to zip the files before uploading.

  
@Override
public void uploadFile(String sourceFilePath, String remoteDirPath, boolean compressed) throws Exception {
	doInSftpSession(sftpClient -> {
		System.out.println("SSHJ UPLOAD FILE FROM "+sourceFilePath+" TO "+remoteDirPath);
		if (compressed) {
			sftpClient.put(new ZipStreamSourceFile(new File(sourceFilePath)), remoteDirPath);
		} else {
			sftpClient.put(sourceFilePath, remoteDirPath);
		}
		return null;
	});
}
  
 

That's all about Create ZIP Stream Before Uploading Files to SFTP. Hope this post is useful to someone.

Comments

Popular posts from this blog

Creating ISO8583 Server using Spring Integration

SFTP Client using SSHJ