--quiet is a GNU-ism; if you want it to work with any POSIX cmp you should use -s.
Of course, this won’t work on Windows. It would be pretty easy to write an equivalent Julia function, though, like:
function filecmp(path1::AbstractString, path2::AbstractString)
stat1, stat2 = stat(path1), stat(path2)
if !(isfile(stat1) && isfile(stat2)) || filesize(stat1) != filesize(stat2)
return false # or should it throw if a file doesn't exist?
end
stat1 == stat2 && return true # same file
open(path1, "r") do file1
open(path2, "r") do file2
buf1 = Vector{UInt8}(undef, 32768)
buf2 = similar(buf1)
while !eof(file1) && !eof(file2)
n1 = readbytes!(file1, buf1)
n2 = readbytes!(file2, buf2)
n1 != n2 && return false
0 != Base._memcmp(buf1, buf2, n1) && return false
end
return eof(file1) == eof(file2)
end
end
end
Not only is this more portable, it is also much faster than executing an external program like cmp. On my Mac laptop it is about 1000× faster in the common case where the file sizes differ, and about 60× faster for a 20kB file when the files match (so that the whole files need to be read).
(Python provides filecmp.cmp in its standard library, I wonder if Julia should too?)
True, it’s on the border between basic enough to include in stdlib and not-needed-often-enough to belong in stdlib. On the other hand, what I like about it is that the API is absolutely crystal clear and won’t change—comparing two files to see if they’re bit-for-bit identical is always going to mean the same thing.
Until feature requests are opened for perfectly reasonable extensions Eg even the dead simple shell command cmp can ignore initial regions, compare up to a given number of bytes, etc.
I don’t indend to be nitpicking here; just given how labor intensive extending anything in Base & the standard libraries is (ramifications, reviews), I am very much against making something an stdlib unless there is a compelling reason.
In any case, the effort can certainly start as a package.
In general people looking at this question are likely interested in DeepDiffs.jl
Which is much older than this question, so I am surprised it isn’t mentioned already
Applying it to files can be done via comaring eachline(file1), eachline(file2)
I used this in julia 1.10, but it seems that new _memcmp now uses pointer instead of higher data structure Vector to compare. This will now throw an error of in julia 1.10. While before julia 1.9.4, this function works fine all the time. The logs are as following
MethodError: no method matching _memcmp(::Vector{UInt8}, ::Vector{UInt8}, ::Int64)
Closest candidates are:
_memcmp(::Union{Ptr{UInt8}, AbstractString}, ::Union{Ptr{UInt8}, AbstractString}, ::Int64)
@ Base strings/string.jl:129
Yeah, in the longer run if you are using this sort of code you should really write it using documented APIs. Fortunately, calling memcmp is on a Vector{UInt8} is just a 1-line function: