如何以编程方式创建 RAM 磁盘?

Posted

技术标签:

【中文标题】如何以编程方式创建 RAM 磁盘?【英文标题】:How can I create a RAM disk programmatically? 【发布时间】:2012-01-31 07:51:05 【问题描述】:

我不是在寻找调用命令行实用程序的代码,它可以解决问题。我其实很想知道用于创建 RAM 磁盘的 API。

编辑

动机:我有一个第三方库,它需要一个目录名,以便以某种方式处理该目录中的文件。我将这些文件压缩在档案中。我希望将存档解压缩到 RAM 磁盘中,并将第三方传递到该 RAM 磁盘上相应目录的路径。如您所见,内存映射文件对我没有用处

【问题讨论】:

如果你真的考虑RAM disk,在Windows中是没有CreateRAMDisk这样的功能的。我认为您需要查看如何为磁盘创建驱动程序,但磁盘被重定向到 RAM。但是,如果您只想将文件重定向到内存,则使用内存映射文件即可完成任务。 Programmable RAM Disk API for .NET? 的可能重复项 【参考方案1】:

WinFsp 允许您使用纯 c++ 或 dotNet C# 以编程方式定义自己的文件系统。 示例项目是一个保存在 OS RAM 内存中的文件系统。您也可以看看 Dokany

https://github.com/billziss-gh/winfsp

https://github.com/dokan-dev/dokany

【讨论】:

【参考方案2】:

ImDisk 是一款 RAM 磁盘应用程序,可从内存扇区创建虚拟驱动器,并具有可从 .NET 调用的 API。

class RamDisk

    public const string MountPoint = "X:";

    public void createRamDisk()
    

        try
        
            string initializeDisk   = "imdisk -a ";
            string imdiskSize       = "-s 1024M ";
            string mountPoint       = "-m "+ MountPoint + " ";


            ProcessStartInfo procStartInfo  = new ProcessStartInfo();
            procStartInfo.UseShellExecute   = false;
            procStartInfo.CreateNoWindow    = true;
            procStartInfo.FileName          = "cmd";
            procStartInfo.Arguments         = "/C " + initializeDisk + imdiskSize + mountPoint;
            Process.Start(procStartInfo);

            formatRAMDisk();

        
        catch (Exception objException)
        
            Console.WriteLine("There was an Error, while trying to create a ramdisk! Do you have imdisk installed?");
            Console.WriteLine(objException);
        

    

    /**
     * since the format option with imdisk doesn't seem to work
     * use the fomat X: command via cmd
     * 
     * as I would say in german:
     * "Von hinten durch die Brust ins Auge"
     * **/
    private void formatRAMDisk()

        string cmdFormatHDD = "format " + MountPoint + "/Q /FS:NTFS";

        SecureString password = new SecureString();
        password.AppendChar('0');
        password.AppendChar('8');
        password.AppendChar('1');
        password.AppendChar('5');

        ProcessStartInfo formatRAMDiskProcess   = new ProcessStartInfo();
        formatRAMDiskProcess.UseShellExecute    = false;
        formatRAMDiskProcess.CreateNoWindow     = true;
        formatRAMDiskProcess.RedirectStandardInput     = true;
        formatRAMDiskProcess.FileName           = "cmd";
        formatRAMDiskProcess.Verb               = "runas";
        formatRAMDiskProcess.UserName           = "Administrator";
        formatRAMDiskProcess.Password           = password;
        formatRAMDiskProcess.Arguments          = "/C " + cmdFormatHDD;
        Process process                         = Process.Start(formatRAMDiskProcess);

        sendCMDInput(process);
    

    private void sendCMDInput(Process process)
    
        StreamWriter inputWriter = process.StandardInput;
        inputWriter.WriteLine("J");
        inputWriter.Flush();
        inputWriter.WriteLine("RAMDisk for valueable data");
        inputWriter.Flush();
    

    public string getMountPoint()
    
        return MountPoint;
    

【讨论】:

尝试了IMDiskSoftPerfect RAM DIsk,我更喜欢SoftPerfect's。它有更好的性能,只保留了100 MB 的0.2 MB,而IMDisk 则保留了10 MB,并且没有t 需要User Account Control (UAC) 提示来安装驱动器。两者都支持持久选项,但我确实对此进行了测试。【参考方案3】:

本身没有创建 RAM 磁盘的 API。您需要编写自己的设备驱动程序,为系统提供一个新磁盘,并使该设备驱动程序与分配的内存一起工作。

编辑(在 OP 的编辑之后)

您尝试执行的操作通常使用“temp”目录来完成,该目录应该驻留在系统中可用的最快磁盘上。因此,已经有 RAMdisk 的系统可能已经将其临时环境变量设置为指向 RAMdisk 上的文件夹,而没有 RAMdisk 的系统只会承受性能损失,这是他们的问题。

现在,如果由于某种原因您不能依赖系统上存在 RAMdisk,并且您绝对需要尽可能快的性能,那么我认为除了安装第三方之外别无选择(也许可以免费下载,甚至开源)RAM盘,暂时使用,然后卸载。但这很笨拙。

【讨论】:

“编写自己的设备驱动程序”在我看来是“几乎不可能”的同义词...... 是的,我认为全世界愿意承担这样一项任务的人可能适合在一个房间里。 如果没有其他 Win32 API 函数可以创建,为什么 Win32 API 函数 GetDriveType 有一个专门针对 RAM 磁盘的返回值? 我不确定,但我有根据的猜测是 Windows 从每个驱动器的设备驱动程序中获取这一信息,(以及其他功能),所以大多数驱动程序返回“否”,但是 ramdisk 设备驱动程序的作者会让他们的设备驱动程序返回“是”。 到 2019 年 2 月,WinFsp 和 Dokany 已经能够创建存储在 OS RAM 中的文件系统【参考方案4】:

你没有提到语言,所以我的答案是 c# :

内存映射文件包含虚拟内存中文件的内容。文件和内存空间之间的这种映射使包括多个进程的应用程序能够通过直接读取和写入内存来修改文件。从 .NET Framework 版本 4 开始,您可以使用托管代码访问内存映射文件,其方式与本机 Windows 函数访问内存映射文件的方式相同,如 MSDN 库中的在 Win32 中管理内存映射文件中所述。

http://msdn.microsoft.com/en-us/library/dd997372.aspx

MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateOrOpen(
       new FileStream(@"C:\temp\Map.mp", FileMode.Create), // Any stream will do it      
       "MyMemMapFile",                                     // Name
       1024 * 1024,                                        // Size in bytes
       MemoryMappedFileAccess.ReadWrite);                  // Access type

// 创建地图视图并读取它:

using (MemoryMappedViewAccessor FileMap = MemoryMapped.CreateViewAccessor())

       Container NewContainer = new Container();
       FileMap.Read<Container>(4, out NewContainer);

【讨论】:

那是一个内存映射文件。它不是 RAM 磁盘。 @MikeNakis 有Non-persisted memory-mapped filespersisted memory-mapped files msdn.microsoft.com/en-us/library/dd997372.aspx @MikeNakis Non-persisted files are memory-mapped files that are not associated with a file on a disk.

以上是关于如何以编程方式创建 RAM 磁盘?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建虚拟磁盘空间以避免节省硬盘?

如何以编程方式在 linux 上创建 iscsi 目标?

如何以编程方式清理 RAM 可可?

检索磁盘读/写最大速度(以编程方式)

在 macOS High Sierra 上创建 APFS RAM 磁盘

创建数据库并希望写入磁盘而不是保存在 RAM 中