有没有办法将内存缓冲区创建为FILE*.在TiXml中它可以将xml打印到FILE*但我似乎无法将其打印到内存缓冲区.
更新2/TL; DR
是否有一些方法可以防止由于关闭在这些文件上打开的内存映射而刷新Windows临时删除关闭文件的脏页.
是.如果您在初始创建后不需要对文件本身执行任何操作,并且实现了一些命名约定,则可以通过本答案中说明的策略实现.
注意:我仍然非常有兴趣找出导致行为有如此大的差异的原因,具体取决于地图的创建方式和处理/取消映射的顺序.
我一直在研究一些进程间共享内存数据结构的策略,它允许通过使用一系列"内存块"来增加和缩小它在Windows上的承诺容量.
一种可能的方法是使用页面文件支持的命名内存映射作为块内存.这种策略的一个优点是可以用来SEC_RESERVE保留一大块内存地址空间并使用VirtualAllocwith 逐步分配它MEM_COMMIT.缺点似乎是(a)要求具有SeCreateGlobalPrivilege允许在Global\命名空间中使用可共享名称的权限,以及(b)所有提交的内存都有助于系统提交费用的事实.
为了克服这些缺点,我开始研究使用临时文件支持的内存映射.即内存映射在使用FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY标志组合创建的文件上.这似乎是一种推荐的策略,根据例如此博客文章应该防止将映射的内存刷新到磁盘(除非内存压力导致脏映射页面被分页).
然而,我观察到在拥有进程退出之前关闭映射/文件句柄会导致脏页被刷新到磁盘.即使视图/文件句柄不是创建脏页面的那个句柄以及在不同视图中页面被"弄脏"之后打开这些视图/文件句柄时,也会发生这种情况.
似乎更改处理顺序(即首先取消映射视图或首先关闭文件句柄)对启动磁盘刷新的时间有一些影响,但不会影响发生刷新的事实.
所以我的问题是:
- 有没有办法使用临时文件支持的内存映射,并防止它们在关闭映射/文件时刷新脏页,考虑到进程/多个进程中的多个线程可能有这样一个文件的打开句柄/视图?
- 如果不是,观察到的行为的原因是什么?
- 你知道我可能忽略的另一种策略吗?
请参阅下面的(c ++)示例代码,该代码允许在我的系统上重现问题(x64,Win7):
static uint64_t start_ts;
static uint64_t elapsed() {
return ::GetTickCount64() - start_ts;
}
class PageArena {
public:
typedef uint8_t* pointer;
PageArena(int id, const char* base_name, size_t page_sz, size_t chunk_sz, size_t n_chunks, bool dispose_handle_first) : …Run Code Online (Sandbox Code Playgroud) language-agnostic windows winapi temporary-files memory-mapped-files
所有,
我有一个打印到流的程序.我需要在内存中缓冲此流,然后根据需要将每行打印到实际文件中.
由于fprintf()函数调用必须有一个FILE *指针,我需要在内存中使用所述指针寻址空间.我曾使用过该open_memstream()功能,但Windows不支持此功能.
因为malloc()返回一个void *指针,根据需要神奇地转换为必要的指针,我可以使用它作为我的FILE *指针吗?如果是这样,有什么警告?我需要注意空间不足吗?
更新:
在找到了open_memstream()比它应该更难的源之后,看起来他们正在为malloc空间做一个文件流.
既然如此,我已经得到了它们的来源,如果我无法通过mingw获得与Windows交叉编译的工作版本,我将会讨论.
此问题与以下任何现有问题均不重复:
File。详细说明并提供背景:
但少数情况下,它需要有一个单独的应用程序读取它开始使用的数据,Process.Start并将文件名作为命令行参数传递。
stdin,因为其中一些程序需要磁盘上的文件而不是从stdin.此外,虽然它运行的机器有大量 RAM(因此将流缓冲在内存中很好),但它的HDD旋转速度很慢,生锈,这也是避免在磁盘上保存临时文件的进一步原因。
我想避免不必要的缓冲和复制 - 理想情况下,我想将整个 1-10MB 请求流式传输到单个内存缓冲区中,然后将相同的缓冲区暴露给其他进程,并使用相同的缓冲区作为支持一个临时文件。
如果我在 Linux 上,我可以使用tmpfs- 它并不完美:
tmpfs该内存区域,而是tmpfs仍然需要通过写入(即复制)所有内存来填充该文件。数据到其文件描述符 - 这与零拷贝系统的目标背道而驰。Windows 的内置 RAM 磁盘功能仅限于通过第三方设备驱动程序为 RAM 磁盘实现提供基础 - 令我惊讶的是 …
在我生命的大部分时间里,我一直在使用cstdio.现在我想转移到iostream.
假设我有一个名为"foo.cpp"的独立程序,如下所示:
int main(){ // foo.cpp
int x;
std::cin >> x;
std::cout << x + 5 << "\n";
}
Run Code Online (Sandbox Code Playgroud)
在另一个名为"bar.cpp"的程序中,我调用了foo可执行文件.在过去,如果我想将stdin和stdout重定向到一个文件,我会这样使用freopen:
int main(){ // bar.cpp, redirecting stdin and stdout
freopen("foo.in", "r", stdin); // Suppose "foo.in" contains a single integer "42"
freopen("foo.out", "w", stdout);
system("foo.exe"); // "foo.out" will contain "47"
}
Run Code Online (Sandbox Code Playgroud)
现在我想重定向std::cin并std::cout以stringstreams.像这样的东西:
int main(){ // bar.cpp, redirecting cin and cout
std::istringstream instr("62");
std::ostringstream outstr;
std::cin.rdbuf(instr.rdbuf());
std::cout.rdbuf(outstr.rdbuf());
system("foo.exe"); // outstr should contain "67" …Run Code Online (Sandbox Code Playgroud) 嗨,我的内存中有一个图像,我想通过外部FTP库发送它.
此FTP库仅接受标准C FILE,并且此库提供的示例代码仅从硬盘读取数据.在我的应用我不想我的图片存储在硬盘上,然后使用文件变量读取它们,而不是我想要做的转换在我的记忆因此它的速度更快,更专业.
我的形象是的形式uchar *,但我可以把它改成std::String或QByteArray或任何其他类型的字符串.现在我想知道如何拥有一个由我的图像数据填充的文件,这样我就可以将其存储到硬盘中并再次读取.
我的伪代码:
uchar * image = readImage();
FILE * New_Image = String2FileConverter(image); //I need this function
FTP_Upload(New_Image);
Run Code Online (Sandbox Code Playgroud) 我正在编写一个C++应用程序,它需要调用一个期望FILE*打开读取的库函数.我没有该功能的代码 - 对我来说这是一个黑盒子.我需要传递给函数的数据在char*已知大小的缓冲区的内存中.理想情况下,我需要将一个缓冲区包装在一个FILE*结构中并传入它,但我需要所有通常FILE*用于工作的stdio函数来处理我传入的内容,因为我不知道它调用了哪个函数 -当然fread,也可能fseek.代码是一个对性能敏感的代码,所以我想避免将缓冲区写入磁盘,以便我可以FILE*通过它创建一个fopen.有没有办法FILE*让我的内存中的缓冲区允许?像stringstreamc ++中的东西?我的代码需要能够在Windows和Linux上运行.
我已经看到很多人试图写入FILE*内存的问题.我的情况恰恰相反 - 我需要将现有缓冲区呈现为可读的 FILE*.
非常感谢!
PS是的,使用像FILE*这样的C字符串正是我所要求的,不知道我以前找不到它......
不过,如果您可以在Windows上建议解决方案,那将非常有用!