分小部分读取大型二进制文件

发布于 2024-12-15 07:37:54 字数 1438 浏览 1 评论 0原文

我想从硬盘读取大小高达 ~4-5GB 的文件。但不是一次完整的,而是按顺序分成约 100MB 的部分。我想让它尽可能简单和快速,但现在我发现 C++ 的标准方法不适用于大于 2GB 的文件。 我使用 Visual Studio 2008、C++/CLI。有什么建议吗?我尝试使用 CreateFile、ReadFile,但对我来说,它会产生比实际工作更多的问题,或者我错误地使用它们来读取部分大文件。

编辑:示例代码:

创建句柄

hFile = CreateFile(result,          
                  GENERIC_READ,             
                  FILE_SHARE_READ,          
                  NULL,                     
                  OPEN_EXISTING,            
                  FILE_ATTRIBUTE_NORMAL     
                  |FILE_FLAG_NO_BUFFERING               
                  | FILE_FLAG_OVERLAPPED,
                  0);

阅读

lpOverlapped = new OVERLAPPED;
lpOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
lpOverlapped->Offset=10;
lpOverlapped->OffsetHigh=0;
DWORD howMuchWasRead;

BOOLEAN error = false;

do {
    this->lastError = NO_ERROR;
    BOOL bRet = ReadFile(this->hFile,this->fileBuffer,this->currentBufferSize,&howMuchWasRead,lpOverlapped);
    this->lastError = GetLastError(); 
    if (this->lastError == ERROR_IO_PENDING){
        while(!HasOverlappedIoCompleted(this->lpOverlapped)){}
        error = true;
    } else {
        error = false;
    }
} while (error == true);

此版本现在返回 ERROR_INVALID_PARAMETER 87 (0x57),为 4GB 。 iso 文件,缓冲区大小为 100MB。

I want to read a file from hard disk in size up to ~4-5GB. But not whole at once but in parts of ~100MB in sequence. I want to make it simple and fast as possible, but now I see that that the standard methods from C++ will not work for files bigger than 2GB.
I use Visual Studio 2008, C++/CLI. Any suggestions? I try to use CreateFile, ReadFile but for me it makes more problems than really works, or I use them wrong for reading a big file in parts.

EDIT: Sample code:

Creating handle

hFile = CreateFile(result,          
                  GENERIC_READ,             
                  FILE_SHARE_READ,          
                  NULL,                     
                  OPEN_EXISTING,            
                  FILE_ATTRIBUTE_NORMAL     
                  |FILE_FLAG_NO_BUFFERING               
                  | FILE_FLAG_OVERLAPPED,
                  0);

Reading

lpOverlapped = new OVERLAPPED;
lpOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
lpOverlapped->Offset=10;
lpOverlapped->OffsetHigh=0;
DWORD howMuchWasRead;

BOOLEAN error = false;

do {
    this->lastError = NO_ERROR;
    BOOL bRet = ReadFile(this->hFile,this->fileBuffer,this->currentBufferSize,&howMuchWasRead,lpOverlapped);
    this->lastError = GetLastError(); 
    if (this->lastError == ERROR_IO_PENDING){
        while(!HasOverlappedIoCompleted(this->lpOverlapped)){}
        error = true;
    } else {
        error = false;
    }
} while (error == true);

This version now returns me ERROR_INVALID_PARAMETER 87 (0x57), for 4GB .iso file, buffer size is 100MB.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

久隐师 2024-12-22 07:37:54

You can map parts of the file into the address space of your process using CreateFile, CreateFileMapping and MapViewOfFile.

幼儿园老大 2024-12-22 07:37:54

您可以按顺序读取该文件,没有任何问题。

局限性在于,当您要查找时,fseek 使用 long 参数作为偏移量。如果不在文件中重新定位,或者偏移量始终小于2GB,则没有问题。

You can read the file sequentially without any problems.

The limitations is that fseek uses a long parameter for the offset when you want to seek. If you don't reposition in the file, or the offset is always less than 2GB, there is no problem.

魔法唧唧 2024-12-22 07:37:54

ReadFile 将处理文件大于 2GB,也许您可​​以重新表述您的问题,以便我们可以帮助您找出遇到的问题。

ReadFile will handle files larger than 2GB, maybe you can rephrase your question so we can help you figure out the problems you are having with that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文