У меня есть файл, который состоит из 69-байтовых сообщений. Нет символов EOL — просто сообщение за сообщением. Общее количество байтов в файле составляет ровно 11 465 930 307, что составляет (11 465 930 307/69) = 166 172 903 сообщения.
Моя программа памяти отображает файл в байтовый массив, просматривает каждое 69-байтовое сообщение и извлекает временную метку. Я отслеживаю, на каком номере сообщения я нахожусь, а затем отметка времени и номер сообщения заносятся в RowDetails
объект, который идет в std::vector<RowDetails>
называется to_sort
, так что я могу эффективно сортировать весь файл по отметке времени.
std::cout << "Sorting....." << to_sort.size() << " rows..." << std::endl;
std::sort(std::begin(to_sort), std::end(to_sort));
Однако затем я создаю новый файл, который сортируется:
unsigned long long total_bytes=0;
unsigned long long total_rows=0;
ofstream a_file("D:\\sorted_all");
std::cout << "Outputting " << to_sort.size() << " rows..." << std::endl;
std::cout << "Outputting " << (to_sort.size()*69) << " bytes..." << std::endl;
for(RowDetails rd : to_sort){
for(unsigned long long i = rd.msg_number*69; i<(rd.msg_number*69)+69; i++){
a_file << current_bytes[i];
total_bytes++;
}
total_rows++;
}
std::cout << "Vector rows: "<< total_rows <<std::endl;
std::cout << "Bytes: " << total_bytes <<std::endl;
Мой вывод:
No. of total bytes (before memory-mapping file): 11,465,930,307 CORRECT
Sorting....... 166,172,903 rows CORRECT
Outputting 166,172,903 rows.... CORRECT
Outputting 11,465,930,307 bytes CORRECT
Vector rows: 166,172,903 CORRECT
Bytes: 11,465,930,169 ERROR, THIS SHOULD BE 307, not 169
Как я могу обработать правильное количество строк, но мой счетчик, подсчитывающий общее количество байтов, неверен ??
При просмотре выходного файла в проводнике Windows 7 он указывает размер: 11 503 248 366 байт, хотя исходный входной файл (который я отображал в памяти) показал правильные значения 11 465 930 307.
Это всего лишь предположение на основе предоставленного вами фрагмента кода, но я готов поспорить, что rd.msg_number
это 32-битный тип. Кажется вероятным, что rd.msg_number*69
иногда бы переполнял свой 32-битный результат, вызывая неправильные вычисления в границах внутреннего цикла. Я хотел бы сделать что-то вроде следующего:
for(RowDetails rd : to_sort){
long long msg_offset = (long long)rd.msg_number * 69;
for(unsigned long long i = 0; i < 69; i++){
a_file << current_bytes[msg_offset+i];
total_bytes++;
}
total_rows++;
}
Неправильный размер выходного файла a_file
выходной файл открывается по умолчанию текст режим вместо двоичный Режим. В текстовом режиме stdio выполнит преобразование EOL, которое вам не нужно. Поэтому измените оператор открытия файла на:
ofstream a_file("d:\\sorted_all", ios::out | ios::binary);
Других решений пока нет …