Java JIOパッケージでファイルgrep機能を実装してみる

2009/04/23 18:52Update
TAGS: Java | NIO | grep | ファイル | IO

java.nioは、Java入出力(IO)処理を効率よく行うためのAPI パッケージです。

サンプルコード:
GrepByJavaNIO.java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Java NIOパッケージでファイルをgrepする例
 *
 */
public class GrepByJavaNIO {

    // Charset
    private static final Charset CHARSET = Charset.forName("ISO-8859-15");
    private static final CharsetDecoder DECODER = CHARSET.newDecoder();

    private static final Pattern LINE_PATTERN  = Pattern.compile(".*\r?\n");    //ファイルの一行を表現する正規表現パターン


    /**
     * grep
     * @param f File
     * @param cb CharBuffer。ファイル内容
     * @param pattern Pattern grepパターン
     */
    private static void grep(File f, CharBuffer cb, Pattern pattern) {
        Matcher lineMatcher = LINE_PATTERN.matcher(cb); // 一行ずつ
        Matcher patternMatcher = null; // Pattern matcher
            
        int lines = 0;
        while (lineMatcher.find()) {
            
            lines++;    //行番号
            CharSequence cs = lineMatcher.group(); // 現在の行 文字列
            if (patternMatcher == null) {       
                patternMatcher = pattern.matcher(cs);
            }
            else {
                patternMatcher.reset(cs);
            }
            
            if (patternMatcher.find()) {    //grepパターンに合致する場合
                System.out.print(f + ":" + lines + ":" + cs);
            }
            if (lineMatcher.end() == cb.limit()) {
                break;
            }
        }
    }

    /**
     * grep
     * @param f File
     * @param pattern Pattern
     * @throws IOException IO異常が発生したとき
     */
    private static void grep(File f, Pattern pattern) throws IOException {

        // FileInputStreamオブジェクト
        FileInputStream fis = new FileInputStream(f);
        // FileInputStreamオブジェクトからjava.nio.channels.FileChannelオブジェクト取得
        FileChannel fc = fis.getChannel();

        // ファイルサイズ
        int sz = (int) fc.size();
        //ファイル内容をメモリ(MappedByteBuffer)にマップ
        MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);

        // 指定するCHARSETでCharBufferにdecodeする
        CharBuffer cb = DECODER.decode(bb);

        // grep
        grep(f, cb, pattern);

        // クローズ
        fc.close();
    }

    public static void main(String[] args) {
        if (args.length < 2) {
            System.err.println("Usage: java Grep pattern file...");
            return;
        }
        
        Pattern pattern = Pattern.compile(args[0]);
        for (int i = 1; i < args.length; i++) {
            File f = new File(args[i]);
            try {
                grep(f, pattern);
            } catch (IOException x) {
                System.err.println(f + ": " + x);
            }
        }
    }

}


参考資料


New IO-TECHSCORE-
java.nio API仕様

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation