Skip to content

Instantly share code, notes, and snippets.

@devymex
Created March 16, 2023 06:41
Show Gist options
  • Save devymex/08309b267b8b9504e828d1181cdfcbbe to your computer and use it in GitHub Desktop.
Save devymex/08309b267b8b9504e828d1181cdfcbbe to your computer and use it in GitHub Desktop.
Compares two files to find differences, then fixes the second file to be identical with the first. Useful when copying a large file between two storage devices.
#include <algorithm>
#include <cstring>
#include <fstream>
#include <iostream>
template<typename _Stream>
size_t GetFileSize(_Stream &stream) {
auto nCurPos = stream.tellg();
stream.seekg(0, std::ios::end);
auto nFileSize = stream.tellg();
stream.seekg(nCurPos, std::ios::beg);
return nFileSize;
}
int main(int nArgCnt, char *ppArgs[]) {
std::ifstream src(ppArgs[1], std::ios::binary);
auto nFileSize = GetFileSize(src);
std::fstream dst(ppArgs[2], std::ios::binary | std::ios::in | std::ios::out);
if (nFileSize != GetFileSize(dst)) {
std::cout << "Size not equal" << std::endl;
return -1;
}
size_t nChunkSize = 1024 * 1024 * 1024;
size_t nChunks = (nFileSize + nChunkSize - 1) / nChunkSize;
std::string strSrcBuf, strDstBuf;
for (size_t i = 0; i < nChunks; ++i) {
size_t nReadBeg = i * nChunkSize;
size_t nReadEnd = std::min(nFileSize, (i + 1) * nChunkSize);
size_t nReadSize = nReadEnd - nReadBeg;
strSrcBuf.resize(nReadSize);
strDstBuf.resize(nReadSize);
std::cout << "Reading chunk " << i << std::endl;
dst.seekg(nReadBeg, std::ios::beg);
if (!src.read(const_cast<char*>(strSrcBuf.data()), strSrcBuf.size()) ||
!dst.read(const_cast<char*>(strDstBuf.data()), strDstBuf.size())) {
std::cout << "Read Failed!" << std::endl;
return -1;
}
std::cout << "Comparing chunk " << i << std::endl;
if (std::memcmp(strSrcBuf.data(), strDstBuf.data(), nReadSize) != 0) {
for (size_t j = 0; j < nChunkSize; ++j) {
if (strSrcBuf.data()[j] != strDstBuf.data()[j]) {
auto nPos = nReadBeg + j;
std::cout << "Make same at [" << nPos << "] " << (int)strSrcBuf[j]
<< " vs " << (int)strDstBuf[j] << std::endl;
dst.seekp(nPos);
dst.write(&strSrcBuf[j], 1);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment