相关疑难解决方法(0)

如何使用FILE*写入内存缓冲区?

有没有办法将内存缓冲区创建为FILE*.在TiXml中它可以将xml打印到FILE*但我似乎无法将其打印到内存缓冲区.

c c++

39
推荐指数
5
解决办法
4万
查看次数

是否有一个Windows等同于HANDLEs的fdopen?

在Unix中,如果您有一个文件描述符(例如来自套接字,管道或从父进程继承),您可以FILE*在其上打开一个缓冲的I/O 流fdopen(3).

Windows上是否有等效的HANDLEs?如果你有HANDLE一个从你的父进程继承(从标准输入,标准输出,或标准错误不同),或从一个管道CreatePipe,是有可能得到一个缓冲FILE*从中流?MSDN确实提供了文档_fdopen,但它适用于返回的整数文件描述符_open,而不是通用HANDLE的.

c winapi stdio

29
推荐指数
1
解决办法
8708
查看次数

如何防止在Windows临时删除关闭文件上打开的内存映射刷新到磁盘

更新2/TL; DR

是否有一些方法可以防止由于关闭在这些文件上打开的内存映射而刷新Windows临时删除关闭文件的脏页.

是.如果您在初始创建后不需要对文件本身执行任何操作,并且实现了一些命名约定,则可以通过本答案中说明的策略实现.

注意:我仍然非常有兴趣找出导致行为有如此大的差异的原因,具体取决于地图的创建方式和处理/取消映射的顺序.


我一直在研究一些进程间共享内存数据结构的策略,它允许通过使用一系列"内存块"来增加和缩小它在Windows上的承诺容量.

一种可能的方法是使用页面文件支持的命名内存映射作为块内存.这种策略的一个优点是可以用来SEC_RESERVE保留一大块内存地址空间并使用VirtualAllocwith 逐步分配它MEM_COMMIT.缺点似乎是(a)要求具有SeCreateGlobalPrivilege允许在Global\命名空间中使用可共享名称的权限,以及(b)所有提交的内存都有助于系统提交费用的事实.

为了克服这些缺点,我开始研究使用临时文件支持的内存映射.即内存映射在使用FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY标志组合创建的文件上.这似乎是一种推荐的策略,根据例如此博客文章应该防止将映射的内存刷新到磁盘(除非内存压力导致脏映射页面被分页).

然而,我观察到在拥有进程退出之前关闭映射/文件句柄会导致脏页被刷新到磁盘.即使视图/文件句柄不是创建脏页面的那个句柄以及在不同视图中页面被"弄脏"之后打开这些视图/文件句柄时,也会发生这种情况.

似乎更改处理顺序(即首先取消映射视图或首先关闭文件句柄)对启动磁盘刷新的时间有一些影响,但不会影响发生刷新的事实.

所以我的问题是:

  • 有没有办法使用临时文件支持的内存映射,并防止它们在关闭映射/文件时刷新脏页,考虑到进程/多个进程中的多个线程可能有这样一个文件的打开句柄/视图?
  • 如果不是,观察到的行为的原因是什么?
  • 你知道我可能忽略的另一种策略吗?


更新 一些附加信息:在两个独立(独立)进程中运行下面示例代码的"arena1"和"arena2"部分时,"arena1"是创建共享内存区域的进程,"arena2"是打开的进程它们,对于具有脏页的地图/块,观察到以下行为:

  • 如果在"arena1"过程中的文件句柄之前关闭视图,它刷新这些块在磁盘的什么似乎(部分)的同步过程(即它会阻止几秒钟的处置线程),独立与否的"arena2"流程开始了.
  • 如果在视图之前关闭文件句柄,则只对那些在"arena1"进程中关闭的地图/块进行磁盘刷新,而"arena2"进程仍然具有对这些块的打开句柄,并且它们看起来是"异步"的,即不阻止应用程序线程.

请参阅下面的(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

15
推荐指数
1
解决办法
1510
查看次数

我可以用malloc和隐式转换替换对open_memstream的调用吗?

所有,

我有一个打印到流的程序.我需要在内存中缓冲此流,然后根据需要将每行打印到实际文件中.

由于fprintf()函数调用必须有一个FILE *指针,我需要在内存中使用所述指针寻址空间.我曾使用过该open_memstream()功能,但Windows不支持此功能.

因为malloc()返回一个void *指针,根据需要神奇地转换为必要的指针,我可以使用它作为我的FILE *指针吗?如果是这样,有什么警告?我需要注意空间不足吗?

更新:

在找到了open_memstream()比它应该更难的源之后,看起来他们正在为malloc空间做一个文件流.

既然如此,我已经得到了它们的来源,如果我无法通过mingw获得与Windows交叉编译的工作版本,我将会讨论.

c windows malloc stream

6
推荐指数
1
解决办法
3218
查看次数

我可以在 Windows 中创建一个仅存在于内存中的文件吗?如果可以,如何创建?

此问题与以下任何现有问题均不重复:

  • 如何将仅存在于内存中的对象文件作为文件存储在存储系统中?- 这个问题与Java的API无关File
  • 临时文件只存在于RAM中?- 这与我要问的很接近,除了OP没有询问如何从内存创建文件以共享将它们传递给子进程
  • 我也不是在问 Win32 的内存映射文件 - 因为它们本质上与我所追求的相反:内存映射文件是映射到进程虚拟内存空间的磁盘上的文件 - 而什么我想要的是一个存在于操作系统文件系统(而不是磁盘的物理文件系统)中的文件,就像安装点一样,并且该文件的数据映射到内存中的现有缓冲区。
    • 即,使用内存映射文件,在内存中的特定缓冲区地址和偏移量处写入/写入字节将导致距文件开头相同偏移量处的字节被修改 - 但该文件实际上存在于磁盘上,这这不是我想要的。

详细说明并提供背景:

  • 我有一个 ASP.NET Core 服务器端应用程序,它定期接收大小在 1 到 10MB 之间的请求流。该程序只能在 Windows / Windows Server 上运行,因此使用 Windows 特定的功能就可以了。
  • 75% 的时间我的应用程序只是自行读取这些流,仅此而已。
  • 但少数情况下,它需要有一个单独的应用程序读取它开始使用的数据,Process.Start并将文件名作为命令行参数传递。

    • 它通过将流保存到磁盘上的临时文件并传递该流的文件名,将数据传递到这些单独的应用程序。
    • 不幸的是,它无法将内容写入子进程stdin,因为其中一些程序需要磁盘上的文件而不是从stdin.
  • 此外,虽然它运行的机器有大量 RAM(因此将流缓冲在内存中很好),但它的HDD旋转速度很慢,生锈,这也是避免在磁盘上保存临时文件的进一步原因。

  • 我想避免不必要的缓冲和复制 - 理想情况下,我想将整个 1-10MB 请求流式传输到单个内存缓冲区中,然后将相同的缓冲区暴露给其他进程,使用相同的缓冲区作为支持一个临时文件。

  • 如果我在 Linux 上,我可以使用tmpfs- 它并不完美:

    • 据我所知,现有进程无法指示操作系统获取其虚拟内存的现有区域并将文件映射到tmpfs该内存区域,而是tmpfs仍然需要通过写入(即复制)所有内存来填充该文件。数据到其文件描述符 - 这与零拷贝系统的目标背道而驰。
  • Windows 的内置 RAM 磁盘功能仅限于通过第三方设备驱动程序为 RAM 磁盘实现提供基础 - 令我惊讶的是 …

windows winapi temporary-files memory-mapped-files

6
推荐指数
1
解决办法
5576
查看次数

运行.exe并重定向stdin并退出

在我生命的大部分时间里,我一直在使用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::cinstd::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)

c++ redirect c++11

5
推荐指数
1
解决办法
578
查看次数

如何将字符串转换为标准C文件?

嗨,我的内存中有一个图像,我想通过外部FTP库发送它.

此FTP库仅接受标准C FILE,并且此库提供的示例代码仅从硬盘读取数据.在我的应用我不想我的图片存储在硬盘上,然后使用文件变量读取它们,而不是我想要做的转换在我的记忆因此它的速度更快,更专业.

我的形象是的形式uchar *,但我可以把它改成std::StringQByteArray或任何其他类型的字符串.现在我想知道如何拥有一个由我的图像数据填充的文件,这样我就可以将其存储到硬盘中并再次读取.

我的伪代码:

   uchar * image = readImage();
   FILE * New_Image = String2FileConverter(image); //I need this function
   FTP_Upload(New_Image);
Run Code Online (Sandbox Code Playgroud)

c++

2
推荐指数
1
解决办法
71
查看次数

如何将字符串转换为打开以供读取的FILE*

我正在编写一个C++应用程序,它需要调用一个期望FILE*打开读取的库函数.我没有该功能的代码 - 对我来说这是一个黑盒子.我需要传递给函数的数据在char*已知大小的缓冲区的内存中.理想情况下,我需要将一个缓冲区包装在一个FILE*结构中并传入它,但我需要所有通常FILE*用于工作的stdio函数来处理我传入的内容,因为我不知道它调用了哪个函数 -当然fread,也可能fseek.代码是一个对性能敏感的代码,所以我想避免将缓冲区写入磁盘,以便我可以FILE*通过它创建一个fopen.有没有办法FILE*让我的内存中的缓冲区允许?像stringstreamc ++中的东西?我的代码需要能够在Windows和Linux上运行.

我已经看到很多人试图写入FILE*内存的问题.我的情况恰恰相反 - 我需要将现有缓冲区呈现为可读的 FILE*.

非常感谢!

PS是的,使用像FILE*这样的C字符串正是我所要求的,不知道我以前找不到它......

不过,如果您可以在Windows上建议解决方案,那将非常有用!

c c++

-2
推荐指数
1
解决办法
87
查看次数