2017-01-18 2 views
0

Как я могу прочитать файл с содержимым Unicode с помощью C/C++?Как прочитать файл с содержимым Unicode

Я использовал функцию ReadFile для чтения файла с содержимым Unicode, но у него нет истинного вывода. Я хочу, чтобы иметь буфер, который содержит все содержимое файла

Я использую этот код:

#include <Windows.h> 

int main() 
{ 
    HANDLE hndlRead; 
    OVERLAPPED ol = {0}; 

    CHAR* szReadBuffer; 
    INT fileSize; 

    hndlRead = CreateFileW(L"file", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 

    if (hndlRead != INVALID_HANDLE_VALUE) 
    { 
     fileSize = GetFileSize(hndlRead, NULL); 
     szReadBuffer = (CHAR*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (fileSize)*2); 
     DWORD nb=0; 
     int nSize=fileSize; 
     if (szReadBuffer != NULL) 
     { 
      ReadFile(hndlRead, szReadBuffer, nSize, &nb, &ol); 
     } 
    } 

    return 0; 
} 

Есть ли способ, чтобы правильно прочитать этот файл?

Это пь и szReadBuffer:

enter image description here

Это мое содержимое файла в notpad ++:

enter image description here

+1

Просьба представить более подробную информацию (что файл RDP?) Дайте нам образец кода, что вы пробовали. Кроме того, прочитайте [Как спросить] (http://stackoverflow.com/help/how-to-ask) на SO. – Steeve

+0

RDP-файл - это файл json, sql, txt, ... нет необходимости говорить «что такое файл RDP?» – joe

+0

Я имею в виду, какой формат он? Что он содержит? Каков ваш ожидаемый результат при чтении? – Steeve

ответ

0

Ваш код работает отлично. Он читает файл rdp дословно в памяти.

Вас беспокоит BOM (byte order mark) в начале файла rdp.

Если вы посмотрите на файл Rdp с текстовым редактором (Блокнот, например), вы увидите следующее:

screen mode id:i:2 
use multimon:i:0 
desktopwidth:i:2560 
desktopheight:i:1600 
.... 

Если вы посмотрите на файл Rdp с редактором шестнадцатеричного вы увидите следующее:

0000 FFFE 7300 6300 7200 6500 6500 6E00 2000 ..s.c.r.e.e.n. . 
0008 6D00 6F00 6400 6500 2000 6900 6400 3A00 m.o.d.e. .i.d... 
.... 

FFFE - знак байтового байта, который указывает, что файл является текстовым файлом, закодированным в маленьком концевом UNICODE, поэтому каждый символ принимает 2 байта вместо 1 байта.

После того, как файл для чтения в памяти, вы получите это (0x00318479 быть адресной szReadBuffer указывает на):

enter image description here

  • BTW 1: вы должны вызвать CloseHandle(hndlRead) после того, как файл был прочитан.
  • BTW 2: вы не должны использовать HeapAlloc, а скорее malloc или calloc.

Исправленная программа:

#include <Windows.h> 

int main() 
{ 
    HANDLE hndlRead; 

    WCHAR* szReadBuffer; // WCHAR instead of CHAR 
    INT fileSize; 

    hndlRead = CreateFileW(L"rdp.RDP", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 

    if (hndlRead != INVALID_HANDLE_VALUE) 
    { 
    fileSize = GetFileSize(hndlRead, NULL); 
    szReadBuffer = (WCHAR*)calloc(fileSize + sizeof(WCHAR), 1); // + sizeof(WCHAR) for NUL string terminator 
    DWORD nb = 0; 
    int nSize = fileSize; 
    if (szReadBuffer != NULL) 
    { 
     ReadFile(hndlRead, szReadBuffer, nSize, &nb, NULL); 
    } 

    CloseHandle(hndlRead); // close what we have opened 

    WCHAR *textwithoutbom = szReadBuffer + 1; // skip BOM 

    // put breakpoint here and inspect textwithoutbom 

    free(szReadBuffer); // free what we have allocated 
    } 

    return 0; 
} 
0

Как следует @MickaelWalz, формат файла файла RDP теперь Unicode.

Вот способ для чтения и отображения содержимого этого файла:

  • Использование wchar_t * буфера вместо внесения CHAR * или BYTE * буфера.
  • Проверьте, выполнено ли ReadFile(). bRet == True и nSize == nb.
  • Начните со второго WCHAR, чтобы исключить идентификатор Unicode 0xFFFE.
  • Не забудьте закрыть свой файл CloseHandle(hndlRead);!
#include <stdio.h> 
#include <iostream> 
#include <Windows.h> 

int main() 
{ 
    HANDLE hndlRead; 
    OVERLAPPED ol = {0}; 

    //BYTE* szReadBuffer; 
    INT fileSize; 
    wchar_t *szReadBuffer; 

    hndlRead = CreateFileW(L"rdp.RDP", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 

    if (hndlRead != INVALID_HANDLE_VALUE) 
    { 
     fileSize = GetFileSize(hndlRead, NULL); 
     szReadBuffer = (wchar_t *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (fileSize)*sizeof(wchar_t)); 
     DWORD nb=0; 
     int nSize=fileSize; 
     BOOL bRet; 
     if (szReadBuffer != NULL) 
     { 
      bRet = ReadFile(hndlRead, szReadBuffer, nSize, &nb, &ol); 
      if ((bRet) && (nb == nSize)) { 
       printf("%02X,%02X... %02X\n",szReadBuffer[0],szReadBuffer[1],szReadBuffer[nb-1]); 
       std::wcout << L"info " << (szReadBuffer+1) << L" " << nb << std::endl; 
      } 
     } 
     CloseHandle(hndlRead); 
    } 

    return 0; 
} 
Смежные вопросы