今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

javaでdiffを

開発用のツールとかを作っていると、ソースの差分をとる機能が欲しくなるときがある。

しかし、外部プロセスでdiffを呼ぶのはちょっと重たいし、そもそもWindowsだとdiffは標準で入ってないし、かと言ってfcは微妙だし…。

Javaでdiffができるライブラリとかないかなー、と探したらjava-diff-utilsというのがあった。Apache Licenseなので業務でも利用しやすい。

 

https://code.google.com/p/java-diff-utils/

 

いろいろ機能はありそうだけど、とりあえず最低限の使い方。

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.List;

import difflib.Delta;
import difflib.DiffUtils;
import difflib.Patch;

public class DiffTest {
    
    public static void main(String[] args) throws IOException {
        List<String> oldLines = Files.readAllLines(FileSystems.getDefault().getPath(args[0]), Charset.defaultCharset());
        List<String> newLines = Files.readAllLines(FileSystems.getDefault().getPath(args[1]), Charset.defaultCharset());
        
        Patch patch = DiffUtils.diff(oldLines, newLines);
        for (Delta delta : patch.getDeltas()) {
            System.out.println(String.format("[変更前(%d)行目]", delta.getOriginal().getPosition() + 1));
            for (Object line : delta.getOriginal().getLines()) {
                System.out.println(line);
            }
            
            System.out.println(" ↓");
            
            System.out.println(String.format("[変更後(%d)行目]", delta.getRevised().getPosition() + 1));
            for (Object line : delta.getRevised().getLines()) {
                System.out.println(line);
            }
            System.out.println();
        }
    }

}

第1引数に

AAAAA
BBBBB
CCCCC
DDDDD
EEEEE

という内容のファイル、第2引数に

BBBBB
FFFFF
EEEEE
GGGGG

という内容のファイルを渡すと、

[変更前(1)行目]
AAAAA
 ↓
[変更後(1)行目]

[変更前(3)行目]
CCCCC
DDDDD
 ↓
[変更後(2)行目]
FFFFF

[変更前(6)行目]
 ↓
[変更後(4)行目]
GGGGG

のように出力される。

 

java-diff-utils : 1.2.1