I am trying to write a service which will copy multiple files from one network location to local project file , while i am running the code i am having below observations
I am not able to understand the issue here below is my code
@Override
@SneakyThrows
public boolean createCopyOnNetwork()throws Exception {
boolean isAbleToCopy =false;
List<ChannelSftp.LsEntry> files = findFile(getChannelUsingSftp(), filemask);
byte[] buffer = new byte[1024];
for(ChannelSftp.LsEntry entry : files) {
bis = new BufferedInputStream(getChannelUsingSftp().get(entry.getFilename()));
newFile = new File("downloadedFiles\\"+entry.getFilename());
os = new FileOutputStream(newFile);
bos = new BufferedOutputStream(os);
while( (readCount = bis.read(buffer)) > 0) {
bos.write(buffer, 0, readCount);
isAbleToCopy=true;
}
}
return isAbleToCopy;
}
public List<ChannelSftp.LsEntry> findFile(ChannelSftp sftpChannel, String filemask) throws SftpException, JSchException {
LOG.info("Getting file List using findFile ");
List<ChannelSftp.LsEntry> list = getChannelUsingSftp().ls(filemask);
return list;
}
public ChannelSftp getChannelUsingSftp() throws JSchException, SftpException {
LOG.info("Getting Sftp");
channel = getSessionOnNetwork(smbUsername,host,port).openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp)channel;
sftpChannel.cd(smbPath);
return sftpChannel;
}
public Session getSessionOnNetwork(String smbUsername,String host,int port) throws JSchException {
LOG.info("Getting session on Network");
session= jsch.getSession(smbUsername,host,port);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(smbPassword);
session.connect();
return session;
}
}
You missing calls to close()
each stream after EACH use inside the loop. Using try with resources will help clean-up all streams immediately after use, and change code structure to make use of built in calls of InputStream
and Files
.
for(ChannelSftp.LsEntry entry : files) {
Path path = Path.of("downloadedFiles",entry.getFilename());
try(InputStream is = getChannelUsingSftp().get(entry.getFilename());
OutputStream os = Files.newOutputStream(path))
{
is.transferTo(os);
isAbleToCopy=true;
}
}
You may find that there is a second issue here relating to use of getChannelUsingSftp()
inside the loop, so that each file retrieval makes a reconnection to ftp server and is not re-using the connection made to same server when generating the list of files as for findFile
. Assigning to a local variable should help avoid excessive server connections:
ChannelSftp ftp = getChannelUsingSftp();