BadCats
@BadCats

Два одинаковых файла имеют разный размер в байтах?

В директории имеется два одинаковых текстовых файла: SomeTxtFile1 и SomeTxtFile2 - оба весом в 1 кб (отображается в проводнике)
При проверке вот таким кодом:
ifs1.open("SomeTxtFile1", ios::binary);
	ifs2.open("SomeTxtFile2", ios::binary);

	int file1Length, file2Length;
	if (ifs1.is_open() && ifs2.is_open())
	{
		ifs1.clear();
		ifs2.clear();
		ifs1.seekg(0, ios::end);
		file1Length = ifs1.tellg();
		ifs2.seekg(0, ios::end);
		file2Length = ifs2.tellg();
		ifs1.clear();
		ifs2.clear();
		if (file1Length == file2Length)
		{
			ifs1.clear();
			ifs2.clear();
			ifs1.seekg(0, ios::beg);
			ifs2.seekg(0, ios::beg);
			char* file1Data = new char[file1Length];
			char* file2Data = new char[file2Length];
			ifs1.read((char*)& file1Data, file1Length);
			ifs2.read((char*)& file2Data, file2Length);
			int rowsCount = 0;
			for (int i = 0; i < file1Length; i++)
			{
				if (file1Data[i] == '\r\n')
				{
					rowsCount++;
				}

				if (file1Data[i] != file2Data[i])
				{
					cout << "в строке " + rowsCount;
				}

			}
		}
		else
		{
			cout << "разный размер файлов"<<endl;
		}
	}

file1Length1 - имеет размер 318, а file1Length2 - 314. SomeTxtFile2 - побывал создавать и как копию SomeTxtFile1 и полностью заново - скопировав все содержимое SomeTxtFile1 - через ctrl+a. Файлы лежат на одном разделе диска, в одной директории.
  • Вопрос задан
  • 169 просмотров
Решения вопроса 2
@antonwx
2 варианта:
1) BOM
2. В одном файле в качестве переноса строки используется \r\n, в другом - \n
Ответ написан
Комментировать
myjcom
@myjcom Куратор тега C++
BadCats,
см. binary mode
гарантируется что при записи двоичных данных в файл и последующем чтении двоичных данных из этого файла данные будут совпадать, равно как и при записи текстовых данных в файл и последующем чтении текстовых данных из этого файла.

При записи текстовых данных в файл и последующей интерпретации их, при чтении, как двоичных, равно как и наоборот, ничего не гарантируется.

Поэкспериментируй

#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <random>
#include <iterator>
#include <experimental/filesystem>
using namespace std;
namespace fs = experimental::filesystem;

void fill_random(vector<char>& data)
{
  std::random_device rd;
  std::mt19937 gen(rd());
  std::uniform_int_distribution<> dis(0, 255);
  generate(data.begin(), data.end(), [&]{ return dis(gen); });
}

int main()
{
  vector<char> content(318);

  fill_random(content); // для чистоты эксперимента

  vector<char> content_copy;

  if(fs::exists("temp"))
  {
    cout << "delete temp dir\n";
    fs::remove_all("temp");
  }

  fs::create_directory("temp");
  cout << "create temp dir\n";

  if(auto file = ofstream("temp/file", ios_base::binary); file)
  {
    file.write(content.data(), content.size());
    cout << "write " << content.size() << " bytes\n";
  }

  if(fs::exists("temp/file"))
  {
    cout << "create copy..." << "\n";
    fs::copy_file("temp/file", "temp/file_copy");
  }
 
  if(fs::file_size("temp/file") == fs::file_size("temp/file_copy"))
  {
    auto file = ifstream("temp/file_copy", ios_base::binary);
    content_copy.resize(fs::file_size("temp/file_copy"));
    file.read(content_copy.data(), content_copy.size());
  }

  auto eq = memcmp(content.data(), content_copy.data(), content.size());

  if(eq == 0)
  {
    cout << "temp/file eq temp/file_copy\n"
         << "file size      == " << fs::file_size("temp/file") << "\n"
         << "file_copy size == " << fs::file_size("temp/file_copy") << endl;
  }

  if(auto text_file = ofstream("temp/text_file"); text_file)
  {
    copy(content.begin(), content.end(), ostream_iterator<char>(text_file));
  }
  
  if(fs::file_size("temp/file") == fs::file_size("temp/text_file"))
  {
    cout << "temp/file eq temp/text_file\n";
  }
  else
  {
    cout << "Surprise\n"
         << R"(fs::file_size("temp/file") == )" << fs::file_size("temp/file") << "\n"
         << R"(fs::file_size("temp/text_file") == )" << fs::file_size("temp/text_file") << endl;
  }

  cin.get();
}


P.S.
Если ещё конкретнее

Binary and text modes
A text stream is an ordered sequence of characters composed into lines (zero or more characters plus a terminating '\n'). Whether the last line requires a terminating '\n' is implementation-defined. Characters may have to be added, altered, or deleted on input and output to conform to the conventions for representing text in the OS (in particular, C streams on Windows OS convert \n to \r\n on output, and convert \r\n to \n on input)

Data read in from a text stream is guaranteed to compare equal to the data that were earlier written out to that stream only if all of the following is true:

the data consist only of printing characters and the control characters \t and \n (in particular, on Windows OS, the character '\0x1A' terminates input)
no \n is immediately preceded by a space character (space characters that are written out immediately before a \n may disappear when read)
the last character is \n
A binary stream is an ordered sequence of characters that can transparently record internal data. Data read in from a binary stream always equals to the data that were earlier written out to that stream. Implementations are only allowed to append a number of null characters to the end of the stream. A wide binary stream doesn't need to end in the initial shift state.

POSIX implementations do not distinguish between text and binary streams (there is no special mapping for \n or any other characters)
Windows не POSIX.

При чтении/записи данных в файл, текстовый редактор читает/пишет данные в "режиме текста" . Для записи/просмотра двоичных данных, нужен соответствующий просмоторщик/редактор.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы