将内存流表示为物理文件

5
我今天遇到了一个愚蠢的问题:
在我的项目中,我必须使用一个库(我不能替换它),但问题是我正在使用MemoryStream而不是频繁保存到硬盘(因为有很多文件,它们的大小很小,所以使用 Memory Stream 很完美)。问题是库API是围绕文件系统访问构建的 - 其中一个函数仅接受对文件的直接路径。
那么我如何仍然可以将字符串(路径)发送到该方法中,从而创建一个新的FileStream而不实际接触硬盘?
例如 "\MEMORY\myfile.bin"?

1
如果文件很小,只需使用FileStream即可。操作系统文件系统可能会将文件内容缓存到RAM中。如果您担心从单个线程写入数千个文件的性能问题,则可以尝试使用FileStream提供的异步BeginWrite操作。 - Monroe Thomas
1
回调文件系统可以在这里使用:http://www.eldos.com/cbfs/ - Raman Zhylich
4个回答

1

嗯,这是个好问题。
基本上,你有三种可能的解决方案:

  1. 你可以使用反射器来修改给定的库。
  2. 你可以检查适当的方法,然后通过使用一些反射魔法,在运行时修改对象(非常不推荐)
  3. 你可以玩弄系统调用和API - 通过进入低级ring0汇编修改kernal.dll以将I/O查询从你的路径引用到内存中。 (也许可以在没有ring0访问权限的情况下实现 - 我不确定)。

显然,最推荐的是使用反射器来修改给定的库。否则,我看不出你有什么解决办法。

回应第一个评论,你可以:
使用RAMDrive(一种分配系统内存小块并显示为分区的程序)


鉴于.NET没有提供这样的选项(微软为什么难以实现呢?),我决定使用RAMDrive(一种程序,它分配系统内存的小块并将其显示为分区)。 - Anonymous
我不知道这样的程序。那是一个公平的解决方案。 - Mark Segal
我其实本来想建议这个(RAMDrive),但感觉这样做有点笨拙。 - Jeremy Holovacs

1
如果文件必须存在于磁盘上(只接受磁盘路径),那么主要选项是虚拟文件系统,它可以让您将自定义数据公开为文件系统。有几个选项可供选择,例如已死的Dokan、我们的Solid File System OS Edition和Callback File System(请参阅我们的Virtual Storage产品线的描述),也许Pismo File Mount会起作用(从未仔细查看过)。

1

这完全取决于库是如何构建的。

如果它是一个 100% 托管的库,使用了 FileStream,你可能会陷入困境。

如果它接受提供的文件名并调用本地 WIN32 的 CreateFile 函数,那么就有可能给它提供一些不同于文件的东西,例如命名管道。

为了快速测试是否可能,将 @"\\.\pipe\random_name" 传递给该方法:如果它明确地说它不能打开管道和以 \\.\ 开头的文件名,那么很抱歉。另一方面,如果它说找不到文件,那么你就有机会让它工作。

然后,您可以创建一个 NamedPipeServerStream,并在您的库方法调用前缀中使用相同的名称 \\.\pipe\


0

你不能将它“表示”为一个文件,但是你可以使用StreamWriter类将其“转换”为一个文件。


1
我可以轻松地删除MemoryStream,甚至不需要使用StreamWriter,但我想将此文件保留在内存中,完全不触碰硬盘。 - Anonymous
我理解你的需求,但没有办法这样做。它不是这样工作的。 - Jeremy Holovacs
如果操作者想要保存它,File.SaveAllBytes() 会更加简单和高效。 - H H
你实际上可以使用我们的一些产品。 - Eugene Mayevski 'Callback
@HenkHolterman,我想你是指File.WriteAllBytes()...但我相当确定它只是BinaryWriter.Write()的包装器。 - Jeremy Holovacs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接