В данной инструкции показано, как сравнить два файла через программу на Go. Будет дан способ определить, являются ли файлы идентичными или нет. Также будет дан способ нахождения разницы между двумя файлами.
Как сравнить два файла в Go?
1. Создайте файл comparison.go
со следующим содержимым:
Рекомендуем вам супер TELEGRAM канал по Golang где собраны все материалы для качественного изучения языка. Удивите всех своими знаниями на собеседовании! 😎
Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
package main import ( "bufio" "crypto/md5" "fmt" "io" "os" ) var data = []struct { name string cont string perm os.FileMode }{ {"test1.file", "Hello\nGolang is great", 0666}, {"test2.file", "Hello\nGolang is great", 0666}, {"test3.file", "Not matching\nGolang is great\nLast line", 0666}, } func main() { files := []*os.File{} // Создаем тестовые файлы for _, fData := range data { // Создание файла f, err := os.Create(fData.name) if err != nil { panic(err) } defer f.Close() // Записываем данные в файл _, err = io.WriteString(f, fData.cont) if err != nil { panic(err) } // Добавляем файловый дескриптор в массив files files = append(files, f) } // Сравниваем контрольные суммы файлов checksums := []string{} for _, f := range files { f.Seek(0, 0) // Сброс курсора к началу файла sum, err := getMD5SumString(f) if err != nil { panic(err) } // Добавляем контрольную сумму в общий массив checksums = append(checksums, sum) } fmt.Println("### Сравнение по контрольной сумме ###") compareCheckSum(checksums[0], checksums[1]) compareCheckSum(checksums[0], checksums[2]) fmt.Println("### Сравнение строка за строкой ###") files[0].Seek(0, 0) files[2].Seek(0, 0) compareFileByLine(files[0], files[2]) // Удаляем недавно созданные файлы. for _, val := range data { os.Remove(val.name) } } func getMD5SumString(f *os.File) (string, error) { file1Sum := md5.New() _, err := io.Copy(file1Sum, f) if err != nil { return "", err } return fmt.Sprintf("%X", file1Sum.Sum(nil)), nil } func compareCheckSum(sum1, sum2 string) { match := "совпадают" if sum1 != sum2 { match = " не совпадают" } fmt.Printf("MD5: %s и MD5: %s %s\n", sum1, sum2, match) } func compareLines(line1, line2 string) { sign := "o" if line1 != line2 { sign = "x" } fmt.Printf("%s | %s | %s \n", sign, line1, line2) } func compareFileByLine(f1, f2 *os.File) { sc1 := bufio.NewScanner(f1) sc2 := bufio.NewScanner(f2) for { sc1Bool := sc1.Scan() sc2Bool := sc2.Scan() if !sc1Bool && !sc2Bool { break } compareLines(sc1.Text(), sc2.Text()) } } |
2. Запустите код через go run comparison.go
в главном терминале;
3. Посмотрите на результат:
1 2 3 4 5 6 7 8 |
### Сравнение по контрольной сумме ### MD5: 5A07C1538087CD5B5C365DE52970E0A3 и MD5: 5A07C1538087CD5B5C365DE52970E0A3 совпадают MD5: 5A07C1538087CD5B5C365DE52970E0A3 и MD5: FED2EADA5D1D1EBF745DFDC7D1385E6C не совпадают ### Сравнение строка за строкой ### x | Hello | Not matching o | Golang is great | Golang is great x | | Last line |
Сравнение двух файлов через MD5 их содержимого
Сравнить два файла можно несколькими способами, в данной инструкции описано два основных. В первом делается сравнение всего файла через создание контрольной суммы (MD5) содержимого файла.
В инструкции одной из статей показано, как можно создать MD5 хеш содержимого файла. В таком случае функция getMD5SumString
генерирует контрольную сумму которая являться строкой, а точнее шестнадцатеричным представлением байтового результата MD5. Затем MD5 хеш файлов сравниваются между собой.
Второй подход сравнивает файлы строка за строкой (в данном случае это содержимое строки). Если строки не совпадают, выводится знак x
. Таким же способом можно сравнить бинарный контент, только вам нужно будет просканировать файл через блоки байтов (срезы байтов).
Администрирую данный сайт с целью распространения как можно большего объема обучающего материала для языка программирования Go. В IT с 2008 года, с тех пор изучаю и применяю интересующие меня технологии. Проявляю огромный интерес к машинному обучению и анализу данных.
E-mail: vasile.buldumac@ati.utm.md
Образование
Технический Университет Молдовы (utm.md), Факультет Вычислительной Техники, Информатики и Микроэлектроники
- 2014 — 2018 Universitatea Tehnică a Moldovei, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Universitatea Tehnică a Moldovei, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»