如何解决使用 JSch 将它们从网络复制到本地路径时文件大小为零
我正在尝试编写一个服务,该服务将多个文件从一个网络位置复制到本地项目文件,同时我正在运行我在下面观察到的代码
- 如果只有一个文件并且说它是 520kb,而通过网络复制时我们有 519kb。
- 如果有多个文件,这些文件会被复制到本地项目路径中,但它们都是 0kb 并且只有来自网络的最后一个文件的数据剩余量为 0kb。
- 文件最初为 0kb,但有时会显示实际大小。
我无法理解下面的问题是我的代码
@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,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,port);
session.setConfig("StrictHostKeyChecking","no");
session.setPassword(smbPassword);
session.connect();
return session;
}
}
解决方法
缓冲的流和写入器必须始终在最后为每个文件刷新。在 while 循环中完成写入后,在流上调用 flush() 。此外,如评论中所述,必须将 while 循环移到 for 循环中。
,在循环内每次使用后,您错过了对 close()
每个流的调用。将 try 与资源一起使用将有助于在使用后立即清理所有流,并更改代码结构以利用 InputStream
和 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
生成文件列表。分配给局部变量应该有助于避免过多的服务器连接:
ChannelSftp ftp = getChannelUsingSftp();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。