read () возвращает неправильное количество байтов, прочитанных в некоторых системах

Я пытаюсь решить проблему чтения файлов в устаревшей системе.

Это 32-битное приложение для Windows, протестированное и работающее только на Windows7 / SP1 / 64-битных системах, на которых установлены одинаковые SP, SDK и IDE. IDE является VS2010 / SP1.

Вот код, о котором идет речь:

#define ANZSEL 20

int ii, bfil, ipos;

if ((bfil = open("Z:\\whatever.bla", O_RDONLY, 0)) == -1)  { goto end; } // please don't complain about this; it's just here because I didn't want to rephrase the if == -1 above and because it's a legacy codebase; i also tried with UNC paths by the way with the same result

ii = read(bfil, &some_struct_instance, sizeof(some_struct));
ipos = _lseek(bfil,0,SEEK_CUR); // ipos shows the correct position here, ie. sizeof(some_struct)
if (ii == sizeof(some_struct))  {

ii = read(bfil, &another_struct_instance, sizeof(another_struct)*ANZSEL); // ii here sometimes shows 15 instead of sizeof(another_struct)*ANZSEL
ipos = _lseek(bfil,0,SEEK_CUR); // ipos always shows the correct value of sizeof(some_struct) + sizeof(another_struct)*ANZSEL
if (ii == sizeof(another_struct)*ANZSEL)  {

// should always come here as long as the files' long enough

Итак, как вы можете видеть, это должен быть простой старый прямой двоичный файл, читаемый в некоторые структуры. Что я мог заметить, так это то, что когда я создаю файл и сначала очищаю структуру с помощью memset / Zeromem, он также «инициализирует» все байты заполнения с 0x00 вместо 0xCC (что является способом Microsoft помечать mem в режиме отладки как не инициализированный stack mem) проблема исчезает в системе, где она не вела себя правильно раньше.

Хотя мне кажется ясным, как я могу «правильно» решить проблему — укажите O_BINARY в open () как

if ((bfil = open("Z:\\whatever.bla", O_RDONLY|O_BINARY, 0)) == -1)

Я понятия не имею, почему это может вести себя так по-другому.
Я попытался просмотреть источники open () и read () в обеих системах, но, поскольку у меня редко есть доступ к единственной системе, где проблема может быть воспроизведена, я пока не смог ничего найти.

Мой вопрос, поэтому, если кто-то может указать, почему это происходит, и ссылаться на некоторые документы.

0

Решение

Обычно это происходит, когда файл содержит значение 0x1a (иначе контроль-Z). Как и MS-DOS до этого, Windows интерпретирует control-Z как сигнал об окончании текстового файла, поэтому, когда вы открываете файл в текстовом режиме, и он достигает 0x1a, он просто прекращает чтение.

Как вы уже обнаружили, открытие файла в двоичном режиме решает проблему — 0x1a больше не интерпретируется как сигнал конца файла.

3

Другие решения


По вопросам рекламы [email protected]