Я пытаюсь решить проблему чтения файлов в устаревшей системе.
Это 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 () в обеих системах, но, поскольку у меня редко есть доступ к единственной системе, где проблема может быть воспроизведена, я пока не смог ничего найти.
Мой вопрос, поэтому, если кто-то может указать, почему это происходит, и ссылаться на некоторые документы.
Обычно это происходит, когда файл содержит значение 0x1a
(иначе контроль-Z). Как и MS-DOS до этого, Windows интерпретирует control-Z как сигнал об окончании текстового файла, поэтому, когда вы открываете файл в текстовом режиме, и он достигает 0x1a, он просто прекращает чтение.
Как вы уже обнаружили, открытие файла в двоичном режиме решает проблему — 0x1a больше не интерпретируется как сигнал конца файла.