【问题标题】:Read 'Binary' files with ReadFile WinAPI使用 ReadFile WinAPI 读取“二进制”文件
【发布时间】:2018-03-23 07:10:28
【问题描述】:

当我尝试使用ReadFile() Windows API 打开“.exe”文件时,它只是返回文件的第 2 个字符,例如:MZ

这是我的代码:

#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);

当我打印ReadBuffer 时,它只是MZ(exe 文件)。

但使用:

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

它工作得很好。 如何使用 ReadFile 读取二进制文件?

【问题讨论】:

  • 如何打印ReadBuffer?作为一个以 NUL 结尾的字符串,我怀疑。当然不是。
  • @IgorTandetnik 我将ReadBuffer 的值放入字符串并使用std::cout 打印字符串
  • 没错。您将其打印为文本数据,但它是二进制数据。它可能在MZ 之后有一个零字节,并且打印在那里停止。
  • @IgorTandetnik 我是这么认为的,因为当我用记事本打开 EXE 文件时,它在 MZ 之后是 NULL。如何忽略 NULL 字符?还是删除它?
  • 而不是std::string val{buffer};使用std::string val{buffer, buffer+dwBytesRead};

标签: c++ file winapi readfile


【解决方案1】:

问题不在于阅读,问题在于打印。

您没有显示您的代码,但您可能尝试使用printf 或类似的方式进行打印。 IOW,您将其打印为 C 字符串。

嗯,二进制数据包括 0,在这种情况下,前 3 个字节是 'M'、'Z'、'\0' - 打印为以空字符结尾的字符串“MZ”。

如果您想看到有意义的二进制数据打印,您必须编写一个转换为每字节十六进制数的转换器:4D 5A 00 等等

【讨论】:

  • 像字符串(或ReadBuffer)到十六进制转换器的东西?
  • ReadBuffer,绝对是ReadBuffervoid *buffer, int readSize
  • std::string(const char*, size_t) 也将用于传递二进制数据。
【解决方案2】:

如何使用 ReadFile 读取二进制文件?

ReadFile(和ReadFileEx)“以二进制模式”工作。您无需任何翻译即可逐字节获取准确的文件内容。

您的书写/打印有问题。这主要取决于您要写入的位置,但是对于在 C++ 中输出可能包含空值的(二进制)数据,请选择 write 方法

some_output_stream.write( buffer_ptr, num_bytes_in_buffer );

some_output_stream 应设置为二进制模式 (std::ios::binary)。如果没有这个标志,所有值为 10 的字节都可以转换为对 13,10。

如果使用 C FILE 函数

fwrite( buffer_ptr, 1, num_bytes_in_buffer, some_output_file );

同样some_output_file 必须处于二进制模式。

在某些情况下,WriteFile 可以用来补充您对 ReadFile 的使用。

【讨论】:

    猜你喜欢
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2019-04-13
    • 2020-11-11
    • 2012-09-11
    • 2019-09-25
    • 2017-06-28
    相关资源
    最近更新 更多