Skip navigation

大きなファイルを読込、行毎にイベントを生成する方法。
Jay Lessik氏による案:

この例は以下のESB Muleコンポーネントを利用します:

その上、以下のJavaクラスも使います(ソースコードを例題の後にあります。):

ステップ 1: ファイル・プロバイダを設定

受信(inbound)トランスフォーマーにNoActionTransformerを指定して、 autoDelete プロパティを「false」に設定します。 moveToDirectory プロパティをファイルを複写するディレクトリ(入力ディレクトリ以外のディレクトリ)に設定します。設定しない場合は、手動でファイルの削除と移動を行う必要があります。以上の設定で、ファイル・プロバイダ(File Provider)はコンポーネントにFileオブジェクトを引き渡します(ファイルの全内容をStringで引き渡す代わりに)。

<connector name="myFileConnector" className="org.mule.providers.file.FileConnector">
    <properties>
        <property name="autoDelete" value="false"/>
        <property name="moveToDirectory" value="file:///myOutputDir"/>
        <map name="serviceOverrides">
            <property name="inbound.transformer" value="org.mule.transformers.NoActionTransformer"/>
        </map>
    </properties>
</connector>

注: ファイル・プロバイダ(File Provider)は処理後にファイルを削除しません。削除する必要がある場合は、削除する処理を別途に設ける必要があります。

ステップ 2: エンドポイントを設定

ステップ1で設定してファイル・プロバイダ(File Provider)と結果を出力するためのSystem.outエンドポイントを指定したファイル・エンドポイントを設定します。

<global-endpoints>
    <endpoint name="myFileEndpoint" address="file:///myInputDir?connector=myFileConnector"/>
    <endpoint name="myOutputEndpoint" address="stream://System.out"/>
</global-endpoints>

注: 送信(outbound)エンドポイントをSystem.outエンドポイント以外に設定することも可能です。本当に大きなファイルを処理する場合は、画面に出力するのではなく、ファイル等のようなものに出力した方がよいと思います。

ステップ 3: ファイル分割ESB Muleコンポーネントを設定

ESB Muleの設定ファイルで、ファイルを分割するファイル分割(file splitter)コンポーネントを設定します。ファイル分割コンポーネントは、ステップ2で設定したファイル(File)・エンドポイントからファイル・メッセージを受信して、FileMessageSplitter送信(outbound)ルータに(ESB MuleのBridgeComponent)を使って)転送します。FileMessageSplitter送信ルータ(outbound-router)は、ファイルを分割して送信(outbound)エンドポイントに送信します。

<mule-descriptor name="myBigFileSplitter" implementation="org.mule.components.simple.BridgeComponent">
    <inbound-router>
        <global-endpoint name="myFileEndpoint"/>
    </inbound-router>
    <outbound-router>
        <router className="test.FileMessageSplitter">
            <global-endpoint name="myOutputEndpoint"/>
        </router>
    </outbound-router>
    <interceptor name="default"/>
</mule-descriptor>

Javaのソース・コード

FileSplitter.java
package test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public interface FileSplitter {
    public void setFile(File file) throws FileNotFoundException;

    public File getFile();

    public String getNextRecord() throws IOException;

    public void close();
}

BufferedFileSplitter.java
package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class BufferedFileSplitter implements FileSplitter 
{
    private File file;
    private BufferedReader bufferedReader;
    private final Log logger = LogFactory.getLog(getClass());

    public BufferedFileSplitter() {
    }

    /**
     * コンストラクタ
     * @param File ファイル
     * @throws FileNotFoundException ファイルがnull又は無い場合
     */
    public BufferedFileSplitter(File file) throws FileNotFoundException {
        if (file == null) {
            throw new FileNotFoundException("ファイルがnullです。");
        }
        this.file = file;
        this.bufferedReader = new BufferedReader(new FileReader(file));
    }

    /**
     * ファイルから次のレコードを取得する。
     *
     * @return 次のレコードの内容を文字列として返します。改行コードやファイルの最後のnullは含まれません。
     * @throws IOException I/Oエラー
     */
    public String getNextRecord() throws IOException {
        if (file == null) {
            throw new IOException("ファイルはnullです。ファイルを読み込む前に設定してください。");
        }
        if (bufferedReader == null) {
            throw new IOException("BufferedReaderがnullです。");
        }
        return bufferedReader.readLine();
    }

    /**
     * BufferedFileSplitterをcloseする。
     */
    public void close() {
        try {
            bufferedReader.close();
        } catch (IOException e) {
            logger.error("BufferedReaderのcloseに失敗しました。", e);
        }
    }

    /**
     * 分割するファイルを取得する。
     *
     * @return File ファイル
     */
    public File getFile() {
        return file;
    }

    /**
     * 分割するファイルを設定する。
     * @param file ファイル
     * @throws FileNotFoundException ファイルがnull又は無い場合。
     */
    public void setFile(File file) throws FileNotFoundException {
        if (file == null) {
            throw new FileNotFoundException("ファイルがnullです。");
        }
        this.file = file;
        this.bufferedReader = new BufferedReader(new FileReader(file));
    }
}

FileMessageSplitter.java
package test;

import org.mule.impl.MuleMessage;
import org.mule.routing.outbound.AbstractMessageSplitter;
import org.mule.umo.UMOMessage;
import org.mule.umo.endpoint.UMOEndpoint;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class FileMessageSplitter extends AbstractMessageSplitter
{
    private FileSplitter fileSplitter;
    private static final ThreadLocal propertiesContext = new ThreadLocal();

    protected void initialise(UMOMessage message) {
        super.initialise(message);

        File payloadFile;

        // メッセージ・タイプをチェック
        Object payload = message.getPayload();
        if (payload instanceof File) 
        {
            payloadFile = (File) payload;
        } 
        else 
        {
            throw new IllegalArgumentException("このルータ(router)のペイロードはjava.io.Fileでなければなりません。");
        }

        try
        {
            fileSplitter = new BufferedFileSplitter(payloadFile);
        }
        catch (FileNotFoundException e)
        {
            throw new IllegalArgumentException("ファイルが見つかりません。ファイル: " + payloadFile.getAbsolutePath());
        }

        // プロパティをキャッシュする。メッセージ・タイプによってはプロパティを取得するのに時間が掛かる
        Map props = new HashMap();
        for (Iterator iterator = message.getPropertyNames().iterator(); iterator.hasNext();)
        {
            String propertyKey = (String) iterator.next();
            props.put(propertyKey, message.getProperty(propertyKey));
        }
        propertiesContext.set(props);
    }

    protected UMOMessage getMessagePart(UMOMessage message, UMOEndpoint endpoint) 
    {
        String record = null;

        try 
        {
            record = fileSplitter.getNextRecord();
        } 
        catch (IOException e) 
        {
            logger.fatal("致命的エラー: " + e.getMessage(), e);
        }

        if (record != null) 
        {
            return new MuleMessage(record, (Map) propertiesContext.get());
        } 
        else 
        {
            return null;
        }
    }
}
Adaptavist Theme Builder Powered by Atlassian Confluence