Как я могу прочитать файл с содержимым Unicode, используя C / C ++?
Я использовал функцию 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;
}
Есть ли способ правильно прочитать этот файл?
Это nb и szReadBuffer:
Это мой файл в notpad ++:
Ваш код работает нормально. Он считывает файл rdp дословно в память.
Вы обеспокоены BOM (метка порядка байтов) в начале файла 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
указывает на):
CloseHandle(hndlRead)
как только файл будет прочитан.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;
}
Как предполагает @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;
}