文件入站通道无法读取文件

时间:2014-03-27 14:25:55

标签: java file-io spring-integration

我使用Spring Integration处理手动添加到文件夹的CSV文件。

我整合的开始是:

<bean id="recursiveScanner" class="org.springframework.integration.file.RecursiveLeafOnlyDirectoryScanner" />
<int-file:inbound-channel-adapter channel="filesIn" directory="file:${integration.directory}" scanner="recursiveScanner">
    <int:poller id="poller" fixed-delay="${integration.delay}" />
</int-file:inbound-channel-adapter>

随后是自定义服务激活器。

当我在扫描目录中移动一个小文件(少量megs)时,它可以正常工作,但当它是一个大文件(93 Mio)时,我得到一个例外:

org.springframework.batch.item.ItemStreamException: Failed to initialize the reader
..........
Caused by: java.io.FileNotFoundException: D:\nreco-import-batch-2014\.\home\entries.csv (Le processus ne peut pas accéder au fichier car ce fichier est utilisé par un autre processus)

它说文件无法被读取,因为已经被另一个进程打开了。

我的猜测是Spring文件在文件传输开始时被触发,当文件仍由操作系统复制时,因此尚不可读。

所以我的问题是:有没有办法配置文件入站通道只有在文件副本完成时才会被触发?

现在我在本地进行测试,两个硬盘之间的传输速率非常好,但应用程序将部署在服务器上,通过FTP访问扫描目录,我相信它会因为文件小得多而失败...

由于


编辑:忘了解释一部分

我的一个服务激活器(最后一个)是一个Spring Batch作业,它解析新添加的文件,处理数据并将它们插入MongoDB数据库

批处理步骤实际读取抛出异常的文件

3 个答案:

答案 0 :(得分:0)

我记得在使用类似于此的应用程序...我们有2个目录......

\ in \用于文件传输...每隔x分钟,它会检查文件是否在那里。一旦文件存在,它将重命名它并将其移动到\ process \目录。

在aix下使用scp并且它处理了非常大的文件。

答案 1 :(得分:0)

所以我最终使用http://blog.on-x.com/2010/11/spring-integration-implementation-d%E2%80%99un-scenario-35中给出的方法,但只有一个自定义过滤器继承了AcceptOnceFileListFilter,由于某种原因,我无法让CompositeFileListFilter工作...... < / p>

public class CustomFileListFilter extends AcceptOnceFileListFilter<File> {

    @Override
    public boolean accept(File file) {

        try {
            FileInputStream stream = new FileInputStream(file);
            stream.close();
        }
        catch (IOException e) {
            log.error("File not readable");
            return false;
        }

        return super.accept(file);
    }

}

我仍然对其他解决方案感兴趣

答案 2 :(得分:0)

我也遇到了这种情况。任何我如何使用上面相同的逻辑来使我的代码工作

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:integration="http://www.springframework.org/schema/integration"
    xmlns:file="http://www.springframework.org/schema/integration/file"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/integration
            http://www.springframework.org/schema/integration/spring-integration.xsd
            http://www.springframework.org/schema/integration/file
            http://www.springframework.org/schema/integration/file/spring-integration-file.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>

    <file:inbound-channel-adapter id="filesIn"
                                 directory="D:\SpringPoller\Input" prevent-duplicates="false">
        <integration:poller id="poller" fixed-delay="5000"/>
    </file:inbound-channel-adapter>

    <integration:service-activator input-channel="filesIn"
                                   output-channel="filesOut"
                                   ref="handler"/>

    <file:outbound-channel-adapter id="filesOut"
                                   directory="D:\SpringPoller\Output"
                                   delete-source-files="true"/>

    <bean id="handler" class="dummy.Handler"/>

</beans>



    package dummy;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;


public class Handler {



    public File handleFile(File input) {
        System.out.println("Copying file: " + input.getAbsolutePath() + "with length :" + input.length());

        // check the file is fully available (full file was copied and no part files processed ...
        FileInputStream stream = null;
        try {
            stream = new FileInputStream(input);

            System.out.println("***********  Stream available now");

        }
        catch (IOException e) {
            System.out.println("##########  Stream not available now");
        }
        finally { 
            try {

                stream.close();
            }catch(Exception e) {

            }
        }


        return input;
    }



}