Java 什么';s使用SFTP Inbound重新下载本地删除的文件的过程
因此,无法找到从远程SFTP重新下载本地删除的文件的正确过程 要求是删除已经从远程SFTP获取的本地文件,并在需要时使用SFTP入站适配器()重新获取相同的文件。在这个实现中,Java 什么';s使用SFTP Inbound重新下载本地删除的文件的过程,java,spring,spring-integration,spring-integration-sftp,Java,Spring,Spring Integration,Spring Integration Sftp,因此,无法找到从远程SFTP重新下载本地删除的文件的正确过程 要求是删除已经从远程SFTP获取的本地文件,并在需要时使用SFTP入站适配器()重新获取相同的文件。在这个实现中,MetadataStore没有被持久化到任何外部系统中,如PropertiesPersistingMetadataStore或Redis元数据存储。因此,根据,元数据存储存储在内存中 找不到任何方法从元数据存储中删除该远程文件的元数据,无法使用文件名重新获取本地删除的文件。而且没有任何线索,这个RemoveToFileMe
MetadataStore
没有被持久化到任何外部系统中,如PropertiesPersistingMetadataStore
或Redis元数据存储。因此,根据,元数据存储
存储在内存中
找不到任何方法从元数据存储中删除该远程文件的元数据,无法使用文件名
重新获取本地删除的文件。而且没有任何线索,这个RemoveToFileMetadata()
回调需要如何实现()
配置类包含以下内容:
@Bean
public IntegrationFlow fileFlow() {
SftpInboundChannelAdapterSpec spec = Sftp.inboundAdapter(sftpConfig.getSftpSessionFactory())
.preserveTimestamp(true)
.patternFilter(Constants.FILE_NAME_CONVENTION)
.remoteDirectory(sftpConfig.getSourceLocation())
.autoCreateLocalDirectory(true)
.deleteRemoteFiles(false)
.localDirectory(new File(sftpConfig.getDestinationLocation()));
return IntegrationFlows
.from(spec, e -> e.id("sftpInboundAdapter").autoStartup(false)
.poller(Pollers.fixedDelay(5000).get()))
.channel(MessageChannels.direct().get())
.handle(message -> {
log.info("Fetching File : " + message.getHeaders().get("file_name").toString());
})
.get();
}
使用ChainFileListFilter
,使用SftpSimplePatternFileListFilter
和sftpersistentAcceptonFileListFilter
使用SimpleMetadataStore
将状态存储在内存(或其他一些元数据存储
)中
newsftpersistentacceptoncefilelistfilter(存储,“somePrefix”)代码>
然后,store.remove(key)
其中key
是somePrefix
+fileName
在localFilter
中使用与filesystemtempersistentaptoncefilelistfilter
类似的筛选器我试图解决这个问题,并使用了的参考代码。我是这样编码的
@Bean
public IntegrationFlow fileFlow() {
SftpInboundChannelAdapterSpec spec = Sftp
.inboundAdapter(sftpConfig.getSftpSessionFactory())
.preserveTimestamp(true)
.filter(sftpFileListFilter())
.localFilter(systemFileListFilter())
.remoteDirectory(sftpConfig.getSourceLocation())
.autoCreateLocalDirectory(true)
.deleteRemoteFiles(false)
.localDirectory(new File(sftpConfig.getDestinationLocation()));
return IntegrationFlows
.from(spec, e -> e.id("sftpInboundAdapter").autoStartup(false)
.poller(Pollers.fixedDelay(5000).get()))
.channel(MessageChannels.direct().get())
.handle(message -> {
log.info("Fetching File : "
+ message.getHeaders().get("file_name").toString());
})
.get();
}
private FileSystemPersistentAcceptOnceFileListFilter systemFileListFilter() {
return new FileSystemPersistentAcceptOnceFileListFilter(store(), prefix);
}
private ChainFileListFilter<ChannelSftp.LsEntry> sftpFileListFilter() {
ChainFileListFilter<ChannelSftp.LsEntry> chainFileListFilter =
new ChainFileListFilter<>();
chainFileListFilter.addFilters(
new SftpPersistentAcceptOnceFileListFilter(store(), prefix),
new SftpSimplePatternFileListFilter(sftpConfig.getFileFilterValue())
);
return chainFileListFilter;
}
@Bean
public SimpleMetadataStore store() {
return new SimpleMetadataStore();
}
我正在得到我想要的文件。它正在为我重新获取文件 我需要像这样创建一个SimpleMetadataStore
bean吗@Bean public SimpleMetadataStore(){return new SimpleMetadataStore();}
我应该使用远程文件或本地文件的绝对路径还是仅使用文件名来构造键
?对于sftp筛选器,它是远程文件名;对于文件系统过滤器,它是绝对路径。请参阅每个筛选器中的fileName()
方法。它是从抽象类中的buildKey()
调用的。谢谢,我错误地添加了sftpersistentAcceptonFileListFilter
filter和SftpSimplePatternFileListFilter
。这很有帮助,但在控制器中,您使用了一种类型来选择绝对路径或仅选择文件名。哪一个对你有用?我添加这些是为了测试。但是遥控器对我有用。
public class Controller {
private final SimpleMetadataStore simpleMetadataStore;
public Controller(SimpleMetadataStore simpleMetadataStore) {
this.simpleMetadataStore = simpleMetadataStore;
}
@GetMapping("/test/remove-metadata/{type}/{fileName}")
@ResponseBody
public String removeFileMetadata(
@PathVariable("fileName") String fileName,
@PathVariable("type") String type
) {
String prefix = definedPrefix;
String filePath = "";
if(type.equals("local")){
filePath = "/local/storage/path/" + fileName;
}else if(type.equals("remote")){
filePath = fileName
}
String key = prefix + filePath;
simpleMetadataStore.remove(key);
return key;
}
}