Tcl:检查两个文件之间的相同内容

时间:2015-03-26 21:37:15

标签: tcl diff

我有一个我在vimscript中创建的程序,它检查两个文件是否相同。它向diff进行系统调用,以验证它们是否是不同的。

我需要在Tcl中使用类似的东西,但不需要使用外部命令或系统调用。我不需要知道差异或文件之间的比较,如果两个文件具有相同的内容则返回1,如果内容不同则返回0。

2 个答案:

答案 0 :(得分:3)

proc comp_file {file1 file2} {
    # optimization: check file size first
    set equal 0
    if {[file size $file1] == [file size $file2]} {
        set fh1 [open $file1 r]
        set fh2 [open $file2 r]
        set equal [string equal [read $fh1] [read $fh2]]
        close $fh1
        close $fh2
    }
    return $equal
}

if {[comp_file /tmp/foo /tmp/bar]} {
    puts "files are equal
}

答案 1 :(得分:2)

对于直接二进制比较,您可以一次只处理一个块。 (虽然你可以选择更大的值,4kB可能已经足够了;但I / O开销在任何情况下都会占主导地位。)表达这一点的最简单方法是使用try ... finally内的循环(需要Tcl 8.6):

proc sameContent {file1 file2} {
    set f1 [open $file1 "rb"]
    set f2 [open $file2 "rb"]
    try {
        while 1 {
            if {[read $f1 4096] ne [read $f2 4096]} {
                return 0
            } elseif {[eof $f1]} {
                # The same if we got to EOF at the same time
                return [eof $f2]
            } elseif {[eof $f2]} {
                return 0
            }
        }
    } finally {
        close $f1
        close $f2
    }
}

否则,我们可以利用这样一个事实:我们可以看到是否已经设置了一个变量来保持逻辑非常简单(这非常不太清楚),以使代码在旧版本的Tcl中工作:

proc sameContent {file1 file2} {
    set f1 [open $file1]
    fconfigure $f1 -translation binary
    set f2 [open $file2]
    fconfigure $f2 -translation binary
    while {![info exist same]} {
        if {[read $f1 4096] ne [read $f2 4096]} {
            set same 0
        } elseif {[eof $f1]} {
            # The same if we got to EOF at the same time
            set same [eof $f2]
        } elseif {[eof $f2]} {
            set same 0
        }
    }
    close $f1
    close $f2
    return $same
}

两者都以相同的方式调用:

if {[sameContent "./foo.txt" "some/dir/bar.txt"]} {
    puts "They're the same contents, byte-for-byte"
} else {
    puts "A difference was found"
}