2

我有一部分项目旨在循环中重新读取文件的某些部分(在指针移动到文件开头之前)。开始时,代码打开文件并正确写入“最小数据”,但进一步读取(在同一文件句柄(!)上)失败,错误代码为 2(“找不到文件”)。

这里是与流程相关的部分代码:

虚拟内存缓冲区.h:

/**
 * Allocates and manages page-aligned virtual memory of the given amount
 */
class VirtualMemBuffer {
public:
    explicit VirtualMemBuffer(size_t size) { /* skipped */ };
/* skipped */
protected:
    void * data;
public:
    const void * buff() const { return this->data; };
};

头文件.h:

static const size_t cFileSize = 4096;

typedef std::map<std::wstring, HANDLE> handlers_conrainer_type;
typedef std::pair<std::wstring, bool> item_type;

class Config {
public:
    typedef std::vector<item_type > container_type;

    container_type files;
    /* skipped */
};

code-file.cpp(在某个函数内):

VirtualMemBuffer buffer(cFileSize);

Config config(...);
config->files.push_back(item_type(L"C:\\lock-file.lock", true));

/* skipped */

for (Config::container_type::const_iterator it = config->files.begin(); 
     it != config->files.end(); 
     ++it)
{
    HANDLE hFile = CreateFile(
        (LPCWSTR)(it->first.c_str()),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        DWORD error = GetLastError();
        // Could not open the file, ignore it
        continue;
    } else {
        DWORD bytes_written = 0;
        BOOL write_ok = WriteFile(
                                    hFile, 
                                    buffer.buff(), 
                                    cFileSize, 
                                    &bytes_written, 
                                    NULL);

        if (!write_ok || (bytes_written != (DWORD)(cFileSize))) {
            // Could not initialize the file, skip the file
            CloseHandle(hFile);
            continue;
        };

        handlers_container.insert(
                std::pair<std::wstring, HANDLE>(it->first, hFile)
                );
    };
};

/* skipped */

for (handlers_conrainer_type::const_iterator it = handlers_container.begin(); 
     it != handlers_container.end(); 
     ++it)
{
    DWORD bytes_read = 0;
    LARGE_INTEGER li;
        li.HighPart = 0;
        li.LowPart = 0;
    BOOL move_ok = SetFilePointerEx(it->second, li, NULL, FILE_BEGIN);
    BOOL read_ok = ReadFile(
                                it->second, 
                                buffer.buff(), 
                                cFileSize, 
                                &bytes_read, 
                                NULL);

    if (!read_ok || (bytes_read != cFileSize)) {
        DWORD error = GetLastError();        // error == 2 :-(
        /* skipped */
    };
};

如您所见,SetFilePointerEx() 和 ReadFile() 都对同一个文件句柄进行操作。第一个(和 CreateFile(), WriteFile() )从未失败,但 ReadFile() 从未成功。

有没有人观察到这种行为,或者至少对此有任何线索?出了什么问题,如何解决(或避免)?

在 Windows XP SP3 上使用 MS Visual C++ 2008 Express Edition 编译的代码

感谢您的时间和建议!

4

2 回答 2

1

我找到了问题的根源——在 MS VC++ 调试器中测试了 ReadFile() 失败的错误代码,其中(以及何时)变量实际上超出了(块)范围,因此被垃圾淹没。值 2 只是这种条件的编译器偏好。

我刚刚注意到并添加了一些进一步的错误检查和代码,并发现真正的错误代码是 998('对内存位置的无效访问'),它本身来自 VirtualMemBuffer 类,其中使用 PAGE_READONLY 标志调用 VirtualAlloc() :-(。

所以,是我的错,对不起。

感谢所有花时间帮助我解决这个问题的人。

于 2011-03-29T20:51:07.700 回答
0

在尝试读取之前尝试 FlushFileBuffers(handle) 将写入提交到磁盘

于 2011-03-29T19:57:46.317 回答