equalfile.go
func (c *Cmp) CompareFile(path1, path2 string) (bool, error) {

	if c.Opt.MaxSize < 0 {
		return false, fmt.Errorf("negative MaxSize")
	}

	r1, openErr1 := os.Open(path1)
	if openErr1 != nil {
		return false, openErr1
	}
	defer r1.Close()
	info1, statErr1 := r1.Stat()
	if statErr1 != nil {
		return false, statErr1
	}

	r2, openErr2 := os.Open(path2)
	if openErr2 != nil {
		return false, openErr2
	}
	defer r2.Close()
	info2, statErr2 := r2.Stat()
	if statErr2 != nil {
		return false, statErr2
	}

	if !c.Opt.ForceFileRead {
		// shortcut: ask the filesystem: are these files the same? (link, pathname, etc)
		if os.SameFile(info1, info2) {
			c.debugf("CompareFile(%s,%s): os reported same file\n", path1, path2)
			return true, nil
		}
	}

	if info1.Mode().IsRegular() && info2.Mode().IsRegular() {
		if info1.Size() != info2.Size() {
			c.debugf("CompareFile(%s,%s): distinct file sizes\n", path1, path2)
			return false, nil
		}
	}

	// If Opt.MaxSize not initialized, set maxSize to an appropriate value
	// for comparing regular files or streams (pipes, devices), etc.
	// Pass maxSize to getHash to ensure the hash is computed only up to
	// the user specified MaxSize amount.
	maxSize := c.Opt.MaxSize
	if maxSize == 0 {
		// If comparing regular to non-regular file, sizes may not
		// agree...  Use the larger value.
		maxSize = info1.Size()
		if maxSize < info2.Size() {
			maxSize = info2.Size()
		}
		if maxSize == 0 { // possible non-regular files
			maxSize = defaultMaxSize
		}
	}

	if c.multipleMode() {
		h1, err1 := c.getHash(path1, maxSize)
		if err1 != nil {
			return false, err1
		}
		h2, err2 := c.getHash(path2, maxSize)
		if err2 != nil {
			return false, err2
		}
		if !bytes.Equal(h1, h2) {
			return false, nil // hashes mismatch
		}
		// hashes match
		if !c.hashMatchCompare {
			return true, nil // accept hash match without byte-by-byte comparison
		}
		// do byte-by-byte comparison
		c.debugf("CompareFile(%s,%s): hash match, will compare bytes\n", path1, path2)
	}

	// Use our maxSize to avoid triggering the defaultMaxSize for files.
	// We still need to preserve the error returning properties of the
	// input amount exceeding MaxSize, so we can't use LimitedReader.
	c.resetDebugging()

	eq, err := c.compareReader(r1, r2, maxSize)

	c.printDebugCompareReader()

	return eq, err
}
func (c *Cmp) CompareFile(path1, path2 string) (bool, error) {

	if c.Opt.MaxSize < 0 {
		return false, fmt.Errorf("negative MaxSize")
	}

	r1, openErr1 := os.Open(path1)
	if openErr1 != nil {
		return false, openErr1
	}
	defer r1.Close()
	info1, statErr1 := r1.Stat()
	if statErr1 != nil {
		return false, statErr1
	}

	r2, openErr2 := os.Open(path2)
	if openErr2 != nil {
		return false, openErr2
	}
	defer r2.Close()
	info2, statErr2 := r2.Stat()
	if statErr2 != nil {
		return false, statErr2
	}

	if !c.Opt.ForceFileRead {
		// shortcut: ask the filesystem: are these files the same? (link, pathname, etc)
		if os.SameFile(info1, info2) {
			c.debugf("CompareFile(%s,%s): os reported same file\n", path1, path2)
			return true, nil
		}
	}

	if info1.Mode().IsRegular() && info2.Mode().IsRegular() {
		if info1.Size() != info2.Size() {
			c.debugf("CompareFile(%s,%s): distinct file sizes\n", path1, path2)
			return false, nil
		}
	}

	// If Opt.MaxSize not initialized, set maxSize to an appropriate value
	// for comparing regular files or streams (pipes, devices), etc.
	// Pass maxSize to getHash to ensure the hash is computed only up to
	// the user specified MaxSize amount.
	maxSize := c.Opt.MaxSize
	if maxSize == 0 {
		// If comparing regular to non-regular file, sizes may not
		// agree...  Use the larger value.
		maxSize = info1.Size()
		if maxSize < info2.Size() {
			maxSize = info2.Size()
		}
		if maxSize == 0 { // possible non-regular files
			maxSize = defaultMaxSize
		}
	}

	if c.multipleMode() {
		h1, err1 := c.getHash(path1, maxSize)
		if err1 != nil {
			return false, err1
		}
		h2, err2 := c.getHash(path2, maxSize)
		if err2 != nil {
			return false, err2
		}
		if !bytes.Equal(h1, h2) {
			return false, nil // hashes mismatch
		}
		// hashes match
		if !c.hashMatchCompare {
			return true, nil // accept hash match without byte-by-byte comparison
		}
		// do byte-by-byte comparison
		c.debugf("CompareFile(%s,%s): hash match, will compare bytes\n", path1, path2)
	}

	// Use our maxSize to avoid triggering the defaultMaxSize for files.
	// We still need to preserve the error returning properties of the
	// input amount exceeding MaxSize, so we can't use LimitedReader.
	c.resetDebugging()

	eq, err := c.compareReader(r1, r2, maxSize)

	c.printDebugCompareReader()

	return eq, err
}
func ( c * Cmp ) CompareFile ( path1 , path2 string ) ( bool , error ) { if c . Opt . MaxSize < 0 { return false , fmt . Errorf ( " " ) } r1 , openErr1 := os . Open ( path1 ) if openErr1 != nil { return false , openErr1 } defer r1 . Close ( ) info1 , statErr1 := r1 . Stat ( ) if statErr1 != nil { return false , statErr1 } r2 , openErr2 := os . Open ( path2 ) if openErr2 != nil { return false , openErr2 } defer r2 . Close ( ) info2 , statErr2 := r2 . Stat ( ) if statErr2 != nil { return false , statErr2 } if ! c . Opt . ForceFileRead { // shortcut: ask the filesystem: are these files the same? (link, pathname, etc) if os . SameFile ( info1 , info2 ) { c . debugf ( " \n " , path1 , path2 ) return true , nil } } if info1 . Mode ( ) . IsRegular ( ) && info2 . Mode ( ) . IsRegular ( ) { if info1 . Size ( ) != info2 . Size ( ) { c . debugf ( " \n " , path1 , path2 ) return false , nil } } // If Opt.MaxSize not initialized, set maxSize to an appropriate value // for comparing regular files or streams (pipes, devices), etc. // Pass maxSize to getHash to ensure the hash is computed only up to // the user specified MaxSize amount. maxSize := c . Opt . MaxSize if maxSize == 0 { // If comparing regular to non-regular file, sizes may not // agree...  Use the larger value. maxSize = info1 . Size ( ) if maxSize < info2 . Size ( ) { maxSize = info2 . Size ( ) } if maxSize == 0 { // possible non-regular files maxSize = defaultMaxSize } } if c . multipleMode ( ) { h1 , err1 := c . getHash ( path1 , maxSize ) if err1 != nil { return false , err1 } h2 , err2 := c . getHash ( path2 , maxSize ) if err2 != nil { return false , err2 } if ! bytes . Equal ( h1 , h2 ) { return false , nil // hashes mismatch } // hashes match if ! c . hashMatchCompare { return true , nil // accept hash match without byte-by-byte comparison } // do byte-by-byte comparison c . debugf ( " \n " , path1 , path2 ) } // Use our maxSize to avoid triggering the defaultMaxSize for files. // We still need to preserve the error returning properties of the // input amount exceeding MaxSize, so we can't use LimitedReader. c . resetDebugging ( ) eq , err := c . compareReader ( r1 , r2 , maxSize ) c . printDebugCompareReader ( ) return eq , err }
// CompareFile verifies that files with names path1, path2 have same contents.
CompareFile verifies that files with names path1 path2 have same contents .