问题标签 [file-mapping]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 在不使指针无效的情况下调整 Windows 上的内存映射文件的大小
我想在 Windows 上调整内存映射文件的大小,而不会使从先前调用中检索到的指针无效MapViewOfFileEx
。这样,所有指向存储在整个应用程序中的任何文件数据的指针都不会因调整大小操作而失效。
我找到了解决问题的方法,但我不确定这种方法是否真的能保证在所有情况下都有效。
这是我的方法:我保留了一个大内存区域VirtualAlloc
:
每次调整内存映射大小时,我都会关闭旧文件映射,释放保留的页面并保留当前文件大小不需要的其余页面:
然后我可以用以下方式映射视图MapViewOfFileEx
:
这种方法是否足够稳定以保证潜在的问题永远不会发生?我是否需要任何同步来避免多线程问题?
编辑:我知道最稳定的方法是更改应用程序的其余部分以允许使所有文件数据指针无效,但这种解决方案可能是一种反映mmap
Linux 行为的简单方法。
winapi - 什么时候应该在 WIN32 API 编程中使用“内存操作机制”?
我正在学习 WINAPI 编程并通过编写 winapi 代码做一些实验。当我转向“使用 winapi 进行内存管理”主题时,我看到有一些“内存操作机制”是
但我无法理解,何时使用虚拟内存以及何时使用堆机制类似地用于内存映射文件。使用其中任何一个的实时示例是什么,或者从程序员的角度来看,在哪种情况下我必须更喜欢虚拟内存、映射文件、堆?
winapi - Windows 文件映射(命名)是否因文件覆盖而失效?
我们有一个数据处理引擎,它使用在第一次使用 Windows API 中的 CreateFile 和 CreateFileMapping 打开时映射到内存中的参考数据。这会导致为读取的文件的每个部分缓存数据,并且缓存会持续存在,直到系统重新启动或需要内存用于其他操作(即使应用程序已关闭并重新打开)。我们定期安装更新的参考数据,我一直在尝试确定是否简单地用新版本覆盖参考文件会使缓存无效,或者是否必须重新启动系统。
我已经尝试在这里和其他地方(包括 MS 文档)进行搜索,但尚未找到明确的答案。我希望有人有一些想法。谢谢。
c - 如何在不知道文件大小的情况下在 Windows 平台中找到内存映射文件的结尾?
我在 Windows 平台上映射了一个未知大小(大约 4-6 GiB)的文件,并获得了一个指向从 MapFileView 函数返回的文件数据开始的指针。但是当我使用指针顺序访问数据时,我怎么知道我已经到达文件的末尾呢?
这是我到目前为止编写的代码,它成功地映射了文件并返回了指针:
所以我想在多个线程中同时读取文件大小相同的不同部分。我相信映射文件是为此目的的正确选择。高度赞赏有关任何其他更快和可能的方法的建议。
我在论坛中研究了一些类似的问题,我想这是我能找到的最接近的主题: Read all contents of memory mapped file or Memory Mapped View Accessor without known the size 但是这个答案是使用 C# 编写的,而不是使用WinAPI,因此,我无法理解他们的过程。
提前致谢 :)
c++ - 如何加载(或映射)文件部分的最大大小,但适合 Windows 上的 RAM?
有大文件。我需要快速排序。我将按部分处理适合 RAM 的文件,以避免/度使用页面文件(下一步:合并部分)。如何使用最大内存?
我的解决方案:使用 WinApi 文件内存映射,但我不知道如何获取文件最大大小的一部分,但适合 RAM(如何确定大小)?
c++ - 如何以类似的方式处理不同的模板?
我已经处理了几天的问题,但仍然没有适当的解决方案。想象一下,我有几种(数量可能不同)乐器。每个仪器产生不同类型的数据。对于每种乐器,我都有一个结构(我在这里展示了非常简单的近似值):
我正在尝试创建一种数据库来查看可用数据。我这样做的方式如下:
首先,我有一个做文件映射的类。我在 Windows 上编程,所以我在函数中使用CreateFile
, CreateFileMapping
,函数:MapViewOdFile
MapFile
然后在结构中使用这个类TMapVector
(我给出一个简化版本):
这个想法是,例如TMapVector<Instrument1>
创建/打开一个对应于Instrument1
并包含类型对象的数据库文件Instrument1
。
现在我遇到的问题是我不知道用户有多少种仪器。目前有 3 个,但代码应该很容易扩展到更多的仪器类型。目前我处理如下。我有一堂TFileInfo
有两种乐器类型的课,但只有一种被填满。这让我可以进一步使用std::vector<TFileInfo>
. 这种方法的问题在于,每次我需要使用仪器做某事时,我都必须使用 switch 语句:
想象一下,如果我需要再添加 10-100 种乐器,当然我不仅有 size() 函数,还有更多。有没有更简单的方法来实现这个?我在考虑接口,但是(1)如果我理解正确的虚函数不能与模板一起使用,(2)我对数据执行相同的操作,只是类型不同。我非常感谢您的建议。
c++ - 在 Linux 与 Windows 上读取大文件(mmap 与 CreateFileMapping/MapViewOfFile)
我必须从一个大文件(超过 7GB)中逐行读取一些数据,它包含顶点坐标列表和面到顶点连接信息以形成网格。我也在学习如何在 Linux 和Windows上使用open
, 。Linux 和 Windows 版本都是 64 位编译的。mmap
CreateFileA
CreateFileMapping
MapViewOfFile
当我在 Linux(使用 docker)上时,g++-10 test.cpp -O3 -std=c++17
我得到了大约 6 秒。当我在 Windows(我的实际 PC)上使用(版本 19.29.30037 x64)cl test.cpp /EHsc /O3 /std:c++17
时,我得到 13s,使用clang++-11
(来自 Visual Studio Build Tools)我得到 11s。
两个系统(同一台 PC,但一个使用 docker)使用相同的确切代码,除了生成const char*
表示内存阵列和表示uint64_t
内存大小的大小。
这是我切换平台的方式:
具体来说,在 char-s 数组中获取内存的代码是:
我对这种解析完全陌生,想知道我在选择 Windows API 中的参数时是否做错了(模仿 mmap 的行为),或者时间差异是否与编译器/系统有关,必须接受?
在 Linux 和 Windows 上,打开、获取内存大小和内存映射的实际时间可以忽略不计,其余代码是相同的,因为它只使用const char*
和size_t
信息进行操作。
感谢您花时间阅读。非常感谢任何提示,如果有任何不清楚的地方,我们深表歉意。
c++ - C++ 创建文件映射对象时 GENERIC_READ 上的初始值设定项过多
我正在尝试创建一个文件映射对象,但遇到了一些编译器错误。(我正在使用 MinGW GCC-8.2.0-3)
我从 VS-code 收到以下错误:too many initializer values
在线GENERIC_READ
。
编译项目时出现以下错误:
我尝试替换GENERIC_READ
为,GENERIC_READ | GENERIC_WRITE
但错误too many initializer value
仍然存在,但仅在GENERIC_READ
. 我尝试过但无济于事的另一件事是CreateFile
用CreateFileA
. 我包括Windows.h
.
我真的很困惑为什么会发生这种情况,因为在WIN32 API 文档下它指出dwDesiredAccess
它通常用作GENERIC_READ
orGENERIC_WRITE
或GENERIC_READ | GENERIC_WRITE
提前致谢!
c++ - SetEndOfFile 错误 1224: ERROR_USER_MAPPED_FILE,即使文件映射关闭成功
我正在编写一个使用文件映射注销到文件的程序。
当我想读取日志时,Logger::Destroy()
会调用,以便将文件映射视图上写入的内容刷新到物理文件中。代码如下:
问题是SetEndOfFile()
失败了ERROR_USER_MAPPED_FILE
,甚至CloseHandle(m_hMapFile)
成功了。所以我用谷歌搜索了微软关于文件映射的手册,并对其中的一些进行了评论。
https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
即使有仍然打开的文件视图,关闭文件映射的句柄也可以成功。有关详细信息,请参阅关闭文件映射对象。
https://docs.microsoft.com/en-us/windows/win32/memory/closing-a-file-mapping-object
当每个进程完成使用文件映射对象并取消映射所有视图时,它必须通过调用 CloseHandle 关闭文件映射对象的句柄和磁盘上的文件。即使有仍然打开的文件视图,这些对 CloseHandle 的调用也会成功。但是,保留文件视图映射会导致内存泄漏。
它说我无法相信 的结果CloseHandle()
。
而且我找不到解决方案。
任何人都可以帮助我吗?谢谢。
补充:我打
Logger::Destroy()
进来了std::lock_guard<std::mutex>
,这对麻烦有影响吗?: 我已经测试过了,锁不影响它。
更新:我已阅读何时出现错误 1224:ERROR_USER_MAPPED_FILE?. 而且我认为没有太大的区别。我附加了
Logger::Initialize()
初始化文件映射的代码。
而且,Logger::Initialize()
两者Logger::Destroy()
都在同一个进程和线程中,无需与他人共享。