使用JSch将文件从网络复制到本地路径时,文件大小为零 [英] File size is zero while copying them from Network to local path using JSch

查看:89
本文介绍了使用JSch将文件从网络复制到本地路径时,文件大小为零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一项服务,该服务将在运行代码时将以下内容从一个网络位置复制多个文件到本地项目文件中

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

  1. 如果只有一个文件,并且说通过网络复制时它为520kb,那么我们有519kb.
  2. 如果有多个文件,这些文件将被复制到本地项目路径中,但所有文件的大小均为0kb,只有来自网络的最后一个文件剩下的数据为0kb.
  3. 文件最初为0kb,但有时会显示实际大小.

我无法理解下面的问题是我的代码

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;
   }

}

推荐答案

每次在循环内使用流之后,您都会丢失对每个流的 close()的调用.使用try资源可以帮助在使用后立即清理所有流,并更改代码结构以利用 InputStream Files 的内置调用.

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;
    }
}

您可能会发现这里还有第二个问题,与循环内使用 getChannelUsingSftp()有关,因此每次文件检索都会重新连接到ftp服务器,而不是重新使用连接生成与 findFile 相同的文件列表时,在同一台服务器上进行.分配给局部变量应该有助于避免服务器之间的过度连接:

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();

这篇关于使用JSch将文件从网络复制到本地路径时,文件大小为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆