Простое чтение файла с помощью ReadFile()

Почему этот код ничего не выводит (кроме информационного слова)? Файл существует.

hReadFile = CreateFile(L"indexing.xml",GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ |FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    wchar_t *wchr = new wchar_t[20];
    DWORD dw;
    ReadFile(hReadFile, wchr, sizeof(wchar_t) * 5, &dw, NULL);
    CloseHandle(hReadFile);
    wchr[dw/sizeof(wchar_t)] = L'\0';
    std::wcout << L"info " << wchr << L"     " << dw << std::endl;

person abilash    schedule 24.10.2012    source источник
comment
Начнем с того, что вы не завершаете строку, которую читаете.   -  person Some programmer dude    schedule 24.10.2012
comment
@Joachim Pileborg Разве ReadFile не прекращает чтение данных автоматически?   -  person abilash    schedule 24.10.2012
comment
@JoachimPileborg: на выходе будет строка, за которой следует мусор   -  person Andrey    schedule 24.10.2012
comment
Что показывает отладчик для wchr после ReadFile?   -  person Andrey    schedule 24.10.2012
comment
@JoachimPileborg Даже мусора нет. Я пытался добавить wchar_t[5] = '\0', но это не помогает   -  person abilash    schedule 24.10.2012
comment
Что вы ожидали от кода? Вы прочитали 5 символов из файла ... Или вы? Возможно, файл не удалось открыть или прочитать не удалось. Вы не тестировали.   -  person paddy    schedule 24.10.2012
comment
@Andrey Debugger говорит, что в wchar есть данные   -  person abilash    schedule 24.10.2012
comment
Возможных причин множество, но наиболее вероятная из них заключается в том, что вы не можете успешно открыть файл. Всегда проверяйте, открываете ли вы файл. Существует множество причин, по которым это может не сработать.   -  person john    schedule 24.10.2012
comment
@Vsevywniy Хорошо, вы не прекратили чтение данных. wchr[dw] = 0;   -  person john    schedule 24.10.2012
comment
@john Я использовал код, который отображается в вопросе редактирования, посмотри на него, но результат тот же   -  person abilash    schedule 24.10.2012
comment
Должно быть wchr[dw/sizeof(wchar_t)] = 0 при условии, что все удалось.   -  person Yakov Galka    schedule 24.10.2012
comment
@ybungalobill тоже ошибается   -  person abilash    schedule 24.10.2012
comment
@Vsevywniy: я не говорил, что это решит проблему. Настоящая проблема заключается в том, что вы используете ReadFile вместо ifstream и UTF-16 вместо UTF-8. Я знаю, что Юникод в Windows — отстой.   -  person Yakov Galka    schedule 24.10.2012
comment
Функция ReadFile не знает, что она читает, для функции файл — это просто поток байтов, и она не знает и не заботится о какой-либо структуре, вы можете наложить структуру (например, завершающие строки, считанные из файла) .   -  person Some programmer dude    schedule 24.10.2012
comment
Я думаю, что проблема в кодировке выходного потока консоли, но как я могу исправить это? Я пытаюсь использовать std::wcout.imbue(std::locale::global(std::locale())); но это не помогает   -  person abilash    schedule 24.10.2012
comment
@ybungalobill, да, моя ошибка.   -  person john    schedule 24.10.2012
comment
Какова ценность dw после возвращения из ReadFile()? Отличается ли он от 0;   -  person alk    schedule 24.10.2012
comment
Проблема со строками Unicode (широкие символы). Он успешно читается в char. И не имеет ничего общего с локалью, поскольку ваш XML - это простой ASCII (я полагаю).   -  person SChepurin    schedule 24.10.2012
comment
Если вы хотите прочитать файл UTF-8 в широких строках char (wchar_t) (UTF-16 в Windows), вам придется использовать MultiByteToWideChar для преобразования из UTF-8 в UTF-16 (wchar_t) и WideCharToMuliByte для преобразования из UTF-16. в UTF-8.   -  person SChepurin    schedule 24.10.2012
comment
@SChepurin, кодировка xml-файла - unicode UTF16   -  person abilash    schedule 24.10.2012
comment
Будет ли std::wcout << L"info " << (wchr+1) << L" " << dw << std::endl; печатать то, что вы ожидаете?   -  person alk    schedule 24.10.2012
comment
@alk ye это работает, спасибо, но почему (wchr+1)?   -  person abilash    schedule 24.10.2012
comment
В случае OP это 2-байтовая спецификация. Подробности смотрите в моем ответе. @Vsevywniy   -  person alk    schedule 24.10.2012


Ответы (1)


Файл Unicode может начинаться с необязательного метки порядка байтов (BOM).

Для UTF-16 спецификация сообщает, какой порядок следования байтов используется в файле.

Также спецификацию можно использовать для различения различных кодировок Unicode.

Файл примера из OP, очевидно, содержит такую ​​спецификацию в качестве первых двух байтов, поскольку увеличение указателя (до wchar_t типизированного массива размером 2 байта) пропускает его и позволяет распечатать данные.

std::wcout << L"info " << (wchr+1) << L" " << dw << std::endl;
person alk    schedule 24.10.2012