Spring SFTP:无法重命名.writing文件

huangapple go评论103阅读模式
英文:

Spring SFTP : Unable to rename .writing file

问题

我正在使用Spring SFTP集成来传输文件,但很多次我都遇到了这个错误。看起来有两个线程尝试传输同一个文件并且彼此冲突。

>2020-08-03 08:31:55,766 INF [task-scheduler-8 ] o.s.i.ftp.session.FtpSession - 文件已成功从以下位置传输:./abc.ext.200803
<br>
>2020-08-03 08:31:55,849 INF [task-scheduler-7 ] o.s.i.ftp.session.FtpSession - 文件已成功从以下位置传输:./abc.ext.200803<br>
>2020-08-03 08:31:55,850 INF [task-scheduler-7 ] .s.i.f.i.FtpInboundFileSynchronizer - 在删除后,无法将'/local/download/abc.ext.200803.writing' 重命名为本地文件'/local/download/abc.ext.200803'。本地文件可能在其他进程中忙碌。<br>

是否有办法让这两个线程不相互干扰?

我正在使用以下代码 -

  1. @Bean
  2. public SftpInboundFileSynchronizer ftpInboundFileSynchronizer() {
  3. isFTPSessionOK();
  4. SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
  5. fileSynchronizer.setPreserveTimestamp(true);
  6. fileSynchronizer.setRemoteDirectory(remoteDirectory);
  7. fileSynchronizer.setDeleteRemoteFiles(false);
  8. fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));
  9. return fileSynchronizer;
  10. }
  11. private boolean isFTPSessionOK() {
  12. try {
  13. SessionFactory&lt;LsEntry&gt; ftpSessionFactory = sftpSessionFactory();
  14. boolean open = ftpSessionFactory.getSession().isOpen();
  15. LOG.info(&quot;FTPSession is good ? &quot; + open);
  16. return open;
  17. } catch (Exception e) {
  18. LOG.error(&quot;FTPSession is not good because of error : &quot; + e);
  19. }
  20. return false;
  21. }
  22. @Bean
  23. public SessionFactory&lt;LsEntry&gt; sftpSessionFactory() {
  24. DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
  25. sf.setHost(server);
  26. sf.setPort(port);
  27. sf.setUser(username);
  28. sf.setPassword(password);
  29. sf.setAllowUnknownKeys(true);
  30. return new CachingSessionFactory&lt;LsEntry&gt;(sf);
  31. }
  32. @Bean
  33. @InboundChannelAdapter(channel = &quot;sftpChannel&quot;, poller = @Poller(fixedDelay = &quot;${${project.name}.ftp.poller.delay:600000}&quot;, maxMessagesPerPoll = &quot;1&quot;))
  34. public MessageSource&lt;File&gt; ftpMessageSource() {
  35. SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
  36. source.setLocalDirectory(new File(localFtpDirectory));
  37. source.setAutoCreateLocalDirectory(true);
  38. return source;
  39. }
  40. @Bean
  41. @ServiceActivator(inputChannel = &quot;sftpChannel&quot;)
  42. public MessageHandler ftpHandler() {
  43. return new MessageHandler() {
  44. @Override
  45. public void handleMessage(Message&lt;?&gt; message) throws MessagingException {
  46. LOG.info(&quot;File &#39;{}&#39; is ready for reading after SFTP&quot;, message.getPayload());
  47. }
  48. };
  49. }
英文:

I am using Spring SFTP integration to transfer the file and many time I got this error. It seems two threads are trying to transfer same file and conflict with each other

>2020-08-03 08:31:55,766 INF [task-scheduler-8 ] o.s.i.ftp.session.FtpSession - File has been successfully transferred from: ./abc.ext.200803
<br>
>2020-08-03 08:31:55,849 INF [task-scheduler-7 ] o.s.i.ftp.session.FtpSession - File has been successfully transferred from: ./abc.ext.200803<br>
>2020-08-03 08:31:55,850 INF [task-scheduler-7 ] .s.i.f.i.FtpInboundFileSynchronizer - Cannot rename '/local/download/abc.ext.200803.writing' to local file '/local/download/abc.ext.200803' after deleting. The local file may be busy in some other process.<br>

Is there a way so both threads should not interfere with each other?

I am using following code -

  1. @Bean
  2. public SftpInboundFileSynchronizer ftpInboundFileSynchronizer() {
  3. isFTPSessionOK();
  4. SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
  5. fileSynchronizer.setPreserveTimestamp(true);
  6. fileSynchronizer.setRemoteDirectory(remoteDirectory);
  7. fileSynchronizer.setDeleteRemoteFiles(false);
  8. fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));
  9. return fileSynchronizer;
  10. }
  11. private boolean isFTPSessionOK() {
  12. try {
  13. SessionFactory&lt;LsEntry&gt; ftpSessionFactory = sftpSessionFactory();
  14. boolean open = ftpSessionFactory.getSession().isOpen();
  15. LOG.info(&quot;FTPSession is good ? &quot; + open);
  16. return open;
  17. } catch (Exception e) {
  18. LOG.error(&quot;FTPSession is not good because of error : &quot; + e);
  19. }
  20. return false;
  21. }
  22. @Bean
  23. public SessionFactory&lt;LsEntry&gt; sftpSessionFactory() {
  24. DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
  25. sf.setHost(server);
  26. sf.setPort(port);
  27. sf.setUser(username);
  28. sf.setPassword(password);
  29. sf.setAllowUnknownKeys(true);
  30. return new CachingSessionFactory&lt;LsEntry&gt;(sf);
  31. }
  32. @Bean
  33. @InboundChannelAdapter(channel = &quot;sftpChannel&quot;, poller = @Poller(fixedDelay = &quot;${${project.name}.ftp.poller.delay:600000}&quot;, maxMessagesPerPoll = &quot;1&quot;))
  34. public MessageSource&lt;File&gt; ftpMessageSource() {
  35. SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(ftpInboundFileSynchronizer());
  36. source.setLocalDirectory(new File(localFtpDirectory));
  37. source.setAutoCreateLocalDirectory(true);
  38. return source;
  39. }
  40. @Bean
  41. @ServiceActivator(inputChannel = &quot;sftpChannel&quot;)
  42. public MessageHandler ftpHandler() {
  43. return new MessageHandler() {
  44. @Override
  45. public void handleMessage(Message&lt;?&gt; message) throws MessagingException {
  46. LOG.info(&quot;File &#39;{}&#39; is ready for reading after SFTP&quot;, message.getPayload());
  47. }
  48. };
  49. }

答案1

得分: 1

以下是要翻译的内容:

你只有这个用于过滤的内容:

fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));

但是怎么样才能防止后续轮询中的重复项呢?

请查看AcceptOnceFileListFilter。并且与SFTPLastModifiedFileFilter一起使用ChainFileListFilter

请查阅文档以获取更多信息:

https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#sftp-inbound

https://docs.spring.io/spring-integration/docs/current/reference/html/file.html#file-reading

英文:

You have only this for filtering:

  1. fileSynchronizer.setFilter(new SFTPLastModifiedFileFilter(remoteFileFilter));

but what about a filter which is going to prevent duplicates on subsequent poll?

See AcceptOnceFileListFilter. And together with that SFTPLastModifiedFileFilter you should use a ChainFileListFilter.

See docs for more info:

https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#sftp-inbound

https://docs.spring.io/spring-integration/docs/current/reference/html/file.html#file-reading

huangapple
  • 本文由 发表于 2020年8月3日 20:30:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/63229482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定