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

Tcl:检查两个文件之间是否有相同的内容,tcl,diff,Tcl,Diff,我有一个用vimscript编写的程序,它检查两个文件是否相同。它对diff进行系统调用,以验证它们是否不同 我需要Tcl中类似的东西,但不需要借助外部命令或系统调用。我不需要知道文件之间的差异或进行比较,只要在两个文件的内容相同时返回1,在内容不同时返回0即可 对于直接的二进制比较,您可以一次只处理一个块。(虽然您可以选择更大的值,但每个块4kB可能足够了;在任何情况下,I/O开销都将占主导地位。)表达这一点的最简单方法是在try…中使用一个循环(需要Tcl 8.6): proc comp_f

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


我需要Tcl中类似的东西,但不需要借助外部命令或系统调用。我不需要知道文件之间的差异或进行比较,只要在两个文件的内容相同时返回1,在内容不同时返回0即可

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

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"
}
否则,我们可以利用这样一个事实,即我们可以看到是否设置了一个变量以保持逻辑相当简单(这一点不太清楚),从而使代码在较旧版本的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"
}

你的角色没有代码、尝试或任何努力?@Jerry我读了J.K.Ousterhout书中的第11章:访问文件,但找不到比较文件的命令。我在网上查过了,但我只能找到文件比较,其中给出/显示了差异,我只是想知道文件是否相同。好的,第一件事是,你的问题看起来像是在要求代码编写服务。也许你应该读这一页(如果你以前至少读过一次,也可以再看一遍)。第二,我本来希望能够更容易地理解您找到的代码,删除不必要的部分以获得您想要的内容,如果有任何问题,那么您可以将问题部分放在问题中,以表明您也付出了努力。@Jerry代码编写服务有什么问题?有些人比我慷慨、善良、知识渊博。为什么我不能从他们那里得到好处?他们是伟大的人,他们总是帮助我。相比之下,我发现很多“堆栈溢出”中的程序员认为,当初学者问“愚蠢”或“愚蠢”的问题时,他们比其他人都好,不幸的是,我在这里发现了很多这样的问题。他们非但没有把他们引向正确的问题,反而开始轻视他们,并且居高临下,这是非常可悲的。IMHO@milapera我想你在这里误解了。也许你应该读一下。我做了一个速度测试。我试着比较不同的文件、文本和二进制文件以及不同的大小,从1KB到70MB。格伦的手术似乎快多了。Tcl 8.6版本平均以21微秒的速度排在最后,而较旧版本则以19微秒的速度排在最后,但Glenn的代码成功地达到了2微秒。我认为区别在于,您的代码经过优化,可以处理二进制文件,而Glenn的代码可以处理文本文件?可能是因为我做了文件大小检查。如果文件明显不同,这将避免文件io。看到Donal的方法,我会将文件大小检查添加到他的逐块读取中。
if {[sameContent "./foo.txt" "some/dir/bar.txt"]} {
    puts "They're the same contents, byte-for-byte"
} else {
    puts "A difference was found"
}