2017-10-11 4 views
0

Wenn ich versuche, Dateien mit ReadFile() Windows-API ‚exe‘ zu öffnen, es ist nur die zwei ersten Zeichen der Datei zurück wie: MZRead ‚Binary‘ Dateien mit Readfile WinAPI

Hier ist mein Code:

#define BUFFERSIZE 5000 

VOID CALLBACK FileIOCompletionRoutine(
__in DWORD dwErrorCode, 
__in DWORD dwNumberOfBytesTransfered, 
__in LPOVERLAPPED lpOverlapped 
); 

VOID CALLBACK FileIOCompletionRoutine(
__in DWORD dwErrorCode, 
__in DWORD dwNumberOfBytesTransfered, 
__in LPOVERLAPPED lpOverlapped) 
{ 
    _tprintf(TEXT("Error code:\t%x\n"), dwErrorCode); 
    _tprintf(TEXT("Number of bytes:\t%x\n"), dwNumberOfBytesTransfered); 
    g_BytesTransferred = dwNumberOfBytesTransfered; 
} 

HANDLE hFile; 
DWORD dwBytesRead = 0; 
char ReadBuffer[BUFFERSIZE] = { 0 }; 
OVERLAPPED ol = { 0 }; 
hFile = CreateFile(fullFilePath.c_str(),    // file to open 
    GENERIC_READ,   // open for reading 
    FILE_SHARE_READ,  // share for reading 
    NULL,     // default security 
    OPEN_EXISTING,   // existing file only 
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // normal file 
    NULL);     // no attr. template 

ReadFileEx(hFile, ReadBuffer, BUFFERSIZE - 1, &ol, FileIOCompletionRoutine); 

Wenn ich drucke ReadBuffer Es ist nur MZ (exe-Datei).

aber unter Verwendung von:

std::ifstream file(argv[1], std::ios::in | std::ios::binary); 

Es ist perfekt. Wie kann ich Binärdateien mit ReadFile lesen?

+2

Wie drucken Sie 'ReadBuffer'? Als eine NUL-terminierte Saite vermute ich. Was natürlich nicht ist. –

+0

@IgorTandetnik Ich lege den Wert von 'ReadBuffer' auf String und drucke String mit' std :: cout' –

+3

Präzise. Sie drucken es als wären es Textdaten, aber es sind Binärdaten. Wahrscheinlich hat es direkt nach "MZ" ein Nullbyte, und der Druckvorgang stoppt dort. –

Antwort

0

Wie kann ich Binärdateien mit ReadFile lesen?

ReadFile (und ReadFileEx) funktioniert 'im Binärmodus'. Sie erhalten den exakten Dateiinhalt Byte für Byte ohne Übersetzung.

Sie haben Probleme mit dem Schreiben/Drucken. Dies hängt vor allem davon, wo Sie schreiben wollen, aber für outputing (binäre) Daten potentiell nulls in C enthalten write Methode

some_output_stream.write(buffer_ptr, num_bytes_in_buffer); 

some_output_stream sollte Binär-Modus (std :: ios :: binary) ++ wählen eingestellt werden. Ohne dieses Flag könnten alle Bytes mit dem Wert 10 in Paare 13, 10 übersetzt werden.

Wenn C Datei-Funktionen verwendet werden

fwrite(buffer_ptr, 1, num_bytes_in_buffer, some_output_file); 

Wieder some_output_file hat im Binärmodus sein.

In einigen Szenarien WriteFile kann ergänzend zu Ihrer Verwendung von ReadFile verwendet werden.

2

Das Problem liegt nicht beim Lesen, das Problem ist beim Drucken.

Sie zeigen Ihren Code nicht, aber Sie versuchen wahrscheinlich, mit printf oder etwas Ähnlichem zu drucken. IOW, du druckst es als C-String.

Nun, binäre Daten enthält 0, und in diesem Fall sind die ersten 3 Bytes 'M', 'Z', '\ 0' - und das druckt als eine Null-terminierte Zeichenfolge "MZ".

Sie müßten einen Konverter pro-Byte-Hex-Zahlen schreiben, wenn Sie sinnvollen Druck von binären Daten sehen wollen: 4D 5A 00 und so weiter

+0

Etwas wie String (oder 'ReadBuffer') zu hex Konverter? –

+0

'ReadBuffer', definitiv' ReadBuffer'. 'void * buffer, int readSize' – Arkadiy

+0

std :: string (const char *, size_t) dient auch dazu, binäre Daten zu übergeben. – Arkadiy