“ReadFile 函数”有没有办法让我不再声明要读取的特定字节数?

Posted

技术标签:

【中文标题】“ReadFile 函数”有没有办法让我不再声明要读取的特定字节数?【英文标题】:"ReadFile Function" is there a way that I can no longer declare specific number of bytes to be read? 【发布时间】:2018-11-14 08:35:32 【问题描述】:

我正在尝试使用 C++ 中的 Windows API 制作程序 目标是读取我创建的文本文件的内容,并能够使用按位 XOR 操作内容(更改为小写和大写,反之亦然),然后将操作后的内容再次放入文本文件中。 这是我使用的程序流程:

    使用 CreateFile 打开文本文件。 将文本文件的内容放在创建的 malloc 上。 使用按位异或 (xor = 20) 操作文本文件的内容。 然后再次将异或值放到文本文件中。

代码如下:

#include "pch.h"
#include <iostream>
#include <windows.h>
using namespace std;

int main()

    HANDLE openFile;
    HANDLE ovewriFile;
    BOOL readwriFile;
    DWORD dwNoByteRead = 0;
    DWORD dwNoByteWritten = 0;
    char *strVal;
    //allocate memory
    strVal = (char*)malloc(sizeof(strVal));
    memset(strVal, '0x00', sizeof(strVal));

    //open a file
    openFile = CreateFile(L"C:\\Users\\John.Doe\\Documents\\test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    //reading the content
    readwriFile = ReadFile(openFile, strVal, 34, &dwNoByteRead, NULL);
    cout << "original content is " << strVal << endl;

    CloseHandle(openFile);

    //manipulate data using xor
    for (int i = 0; i != strlen(strVal); i++) 
        if (strVal[i] == 0x20)
        
            continue;
        
        strVal[i] ^= 0x20;
    
    cout << "xor value: " << strVal << endl;

    //overwrite a file
    ovewriFile = CreateFile(L"C:\\Users\\farrel.moje\\Documents\\test.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    //write the content
    readwriFile = WriteFile(ovewriFile, strVal, 34, &dwNoByteWritten, NULL);

    //just a way to know if successful yung writefile
    if (readwriFile == FALSE) 

        cout << "ERROR WRITING " << GetLastError() << endl;
    
    else 
        cout << "Success Overwrite " << endl;
    
    cout << "Modified content " << strVal << endl;

    CloseHandle(ovewriFile);
    free(strVal);

    return 0;

这个程序正在运行,但是当我尝试将 nNumberOfBytesToRead(要读取的最大字节数)从 34 更改为 sizeof(strVal) 或 strlen(strVal)

readwriFile = ReadFile(openFile, strVal, 34, &dwNoByteRead, NULL);

但是使用 sizeof 和 strlen,它没有显示文本文件的全部内容。 有没有办法让我不再声明要读取的特定字节数?

提前致谢!

【问题讨论】:

你为什么用malloc 我不认为这有足够的内存来保存你的文件的内容strVal = (char*)malloc(sizeof(strVal)); sizeof(strVal) 等于 sizeof (char*),在大多数系统上等于 4 或 8。你为什么认为,这相当于 34? 在同一行论证中,您可以使用goto,只是为了熟悉goto。只是不要这样做。在极少数情况下,您需要在 c++ 中使用 malloc。我还没遇到过 坦率地说,问题是在没有明显理由这样做的情况下,您正在搞乱手动内存分配。 strVal 应该是适当大小的 std::stringstd::vector 【参考方案1】:

删除你的

strVal = (char*)malloc(sizeof(strVal));
memset(strVal, '0x00', sizeof(strVal));

因为这是个坏主意。

更改一些代码以获取文件大小:

openFile = CreateFile(L"C:\\Users\\John.Doe\\Documents\\test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

LARGE_INTEGER fs;
GetFileSizeEx(openFile, &fs);
unsigned long long fSize = fs.QuadPart;
strVal = new char[fSize+1];
memset(strVal, 0, fSize+1);

//reading the content
readwriFile = ReadFile(openFile, strVal, fSize, &dwNoByteRead, NULL)

最后别忘了

delete []strVal;

代替你的free(strVal)

【讨论】:

在 C++ 中,几乎没有理由使用new,当然也没有理由调用delete。请改用std::vector @IInspectable 谢谢你,队长)【参考方案2】:

您可以使用 API GetFileSizeEx() 首先获取文件大小。 此外, sizeof(point) 始终返回 4/8,因为它是该点的大小,而不是您要分配的大小。 添加和更改您的代码,如下所示:

LARGE_INTEGER liFileSize;
//open a file
openFile = CreateFile(L"C:\\Users\\John.Doe\\Documents\\test.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GetFileSizeEx(openFile, &liFileSize);
//allocate memory
strVal = (char*)malloc(liFileSize.QuadPart);
memset(strVal, 0, liFileSize.QuadPart);

那么你可以用“liFileSize.QuadPart”来代替“nNumberOfBytesToRead”(34)

【讨论】:

您解释了 OP 的代码有什么问题,但随后决定做同样的事情sizeof(liFileSize.QuadPart) 计算结果为 8。 @IInspectable ,很抱歉我的书面错误,我已经修复了。 不,你没有。您只是引入了更多未定义的行为。

以上是关于“ReadFile 函数”有没有办法让我不再声明要读取的特定字节数?的主要内容,如果未能解决你的问题,请参考以下文章

CreateFileWriteFileReadFile

有没有办法让我的不和谐机器人在播放完歌曲后断开与语音频道的连接?

当 SSL 证书不再有效时从 https 重定向到 http

如果明天我不再爱你

让你不再害怕指针

匿名管道的 ReadFile 函数