确定文件写入事件何时完成整个文件的写入



这是我的第一个问题,所以请耐心等待。
在最近发布的Spring 5.2中,有一些非常有用的组件添加到Spring Integration中,如以下链接所示:
https://docs.spring.io/spring-integration/reference/html/sftp.html#sftp-server-events
Apache MINA与一个新的侦听器"ApacheMinaSftpEventListener"集成,它

侦听某些 Apache Mina SFTP 服务器事件并将其发布为 ApplicationEvents

到目前为止,我的应用程序可以从提供的链接中捕获文档中所述的应用程序事件,但我似乎无法弄清楚事件何时完成......如果这是有道理的(可能不是(。

在流程中,应用程序作为指定端口上的 SFTP 服务器启动和激活。
我可以使用用户名和密码连接到启动传输的系统上并"放置"文件。
当我登录时,我可以捕获"会话打开事件"当我传输文件时,我可以捕获"文件写入事件"当我注销或断开连接时,我可以捕获"会话关闭事件"当文件较大时,我可以捕获所有"文件写入事件">


事件,它告诉我传输发生在预定或计算大小的缓冲区流上。

我试图确定的是"我如何知道该流何时完成"。这将帮助我回答"作为接受文件的 SFTP 服务器,我什么时候可以访问完成的文件?

My Listener bean(通过SubSystemFactory在启动时附加到Apache Mina(

@Configuration
public class SftpConfiguration {
@Bean
public ApacheMinaSftpEventListener apacheMinaSftpEventListener() {
return new ApacheMinaSftpEventListener();
}   
}
SftpSubsystemFactory subSystem = new SftpSubsystemFactory();
subSystem.addSftpEventListener(listener);

我的事件侦听器:这是在这里,所以我可以在记录器中看到一些输出,当我意识到,在几个GB的文件中,FileWriteEvent有点疯狂。

@Async
@EventListener
public void sftpEventListener(ApacheMinaSftpEvent sftpEvent) {
log.info("Capturing Event: ", sftpEvent.getClass().getSimpleName());
log.info("Event Details: ", sftpEvent.toString());
}

这几件作品是我开始捕捉事件

真正需要的。我在想我需要覆盖一种方法来帮助我在流结束时捕获,以便我可以继续我的业务逻辑,但我不确定是哪一个。
我似乎能够在流完成之前访问文件(读/写(,所以我似乎无法使用尝试"移动"文件并等待它抛出错误的逻辑,尽管这种方法对我来说似乎是不好的做法。

任何指导将不胜感激,谢谢。

版本控制信息

  • 春季 5.2.3
  • 春季启动 2.2.3
  • 阿帕奇米娜 2.1.3
  • 爪哇 1.8

这可能对其他人没有帮助,但我通过集成相关解决方案与本答案中找到的新 Apache MINA 类相结合,找到了解决我最初问题的方法:
https://stackoverflow.com/a/45513680/12806809
我的解决方案:
创建一个类来扩展新的 ApacheMinaSftpEventListener,同时覆盖"打开"和"关闭"方法,以确保我的 SFTP 服务器业务逻辑知道文件何时完成写入。

public class WatcherSftpEventListener extends ApacheMinaSftpEventListener {
...
...
@Override public void open(ServerSession session, String remoteHandle, Handle localHandle) throws IOException {
File file = localHandle.getFile().toFile();
if (file.isFile() && file.exists()) {
log.debug("File Open: {}", file.toString());
}
// Keep around the super call for now
super.open(session, remoteHandle, localHandle);
}
@Override
public void close(ServerSession session, String remoteHandle, Handle localHandle) {
File file = localHandle.getFile().toFile();
if (file.isFile() && file.exists()) {
log.debug("RemoteHandle: {}", remoteHandle);
log.debug("File Closed: {}", file.toString());
for (SftpFileUploadCompleteListener listener : fileReadyListeners) {
try {
listener.onFileReady(file);
} catch (Exception e) {
String msg = String.format("File '%s' caused an error in processing '%s'", file.getName(), e.getMessage());
log.error(msg);
try {
session.disconnect(0, msg);
} catch (IOException io) {
log.error("Could not properly disconnect from session {}; closing future state", session);
session.close(false);
}
}
}
}
// Keep around the super call for now
super.close(session, remoteHandle, localHandle);
}
}

当我启动 SSHD 服务器时,我将我的新侦听器 Bean 添加到 SftpSubsystemFactory 中,该 Bean 使用自定义的事件处理程序类对传入文件应用我的业务逻辑。

watcherSftpEventListener.addFileReadyListener(new SftpFileUploadCompleteListener() {
@Override
public void onFileReady(File file) throws Exception {
new WatcherSftpEventHandler(file, properties.getSftphost());
}
});
subSystem.addSftpEventListener(watcherSftpEventListener);

这个解决方案还有更多,但由于这个问题没有那么多流量,而且现在更多的是供我参考和学习,除非被问到,否则我不会提供更多的东西。

最新更新