【问题标题】:Read and write hard disk sector directly and efficiently [duplicate]直接高效地读写硬盘扇区[重复]
【发布时间】:2013-12-08 07:09:29
【问题描述】:

我对块数据存储有特殊需求。我的数据是4096大小的格式化数据块。为了效率高,我想直接操作硬盘扇区上的块,不想把数据块当作文件。我认为一种方法是将设备视为 /dev/sda1 之类的文件,并使用 lseek() read() 和 write() 来读取和写入数据。但是我不知道文件的头部是否是硬盘的第一个扇区。我也怀疑这种方法的效率。

我正在研究 Linux 操作系统和 C 编程语言。

处理硬盘扇区最有效的方法是什么?我应该写一个linux的块设备模块吗?但是,我对此知之甚少。我应该使用哪些内核函数在块设备上进行读写?

【问题讨论】:

  • 这是:stackoverflow.com/questions/3520459/… 与您相关吗?似乎回答了大多数“如何”的问题,尽管您可能需要对确切的功能进行基础研究。
  • 有关系,但不知道哪种方法对随机访问硬盘的I/O速度有好的表现。
  • 为什么要避免使用文件系统? 鉴于硬盘比 RAM 慢大约一百万倍,而 SSD 比 RAM 慢数千倍,因此该文件系统开销非常小,通常无法察觉。并且磁盘控制器(在磁盘本身内部,因此任何软件都无法避免)如今正在做很多事情(扇区重组等)。例如,您可以使用(来自用户级应用程序)普通的read(2) 访问(数据大小为 4Kbytes 的倍数,并且 4Kbyte 对齐)。此外,文件系统被缓存!
  • @andrewcooke:人们有时会因为“XY 问题”而询问有关问题的更多细节:meta.stackexchange.com/questions/66377/what-is-the-xy-problem - 当问题似乎比其原始问题更具体的解决方案时,这是很常见的事情.
  • @andrewcooke:因为如果我看到有人问如何使用枪来剪指甲,我认为向他解释指甲剪绰绰有余会更有用。

标签: c linux linux-kernel hard-drive


【解决方案1】:

“大小为 4096 的块”并不是特别需要,而且您没有提到任何会破坏内核内置缓存机制的访问模式。

读取和写入数据的最有效方法是使用文件。

【讨论】:

    【解决方案2】:
    int ReadSector(int numSector,char* buf)
    {
        int retCode = 0;
        BYTE sector[512];
        DWORD bytesRead;
        HANDLE device = NULL;
    
        device = CreateFile("\\\\.\\H:",    // Drive to open
            GENERIC_READ,           // Access mode
            FILE_SHARE_READ,        // Share Mode
            NULL,                   // Security Descriptor
            OPEN_EXISTING,          // How to create
            0,                      // File attributes
            NULL);                  // Handle to template
    
        if(device != NULL)
        {
            // Read one sector
            SetFilePointer (device, numSector*512, NULL, FILE_BEGIN) ;
    
            if (!ReadFile(device, sector, 512, &bytesRead, NULL))
            {
                Print("Error in reading1 floppy disk\n",numligne++);
            }
            else
            {
                // Copy boot sector into buffer and set retCode
                memcpy(buf,sector, 512);retCode=1;
            }
    
            CloseHandle(device);
            // Close the handle
        }
    
        return retCode;
    }
    

    这是我读取扇区的功能,写入方法相同。 零扇区将是分区的第一个扇区

    【讨论】:

    • @Daniel:很好的提示,不幸的是你没有提到你在你的函数中使用的所需包含:-)
    • 此代码适用于 Windows,而不是像 OP 要求的那样适用于 Linux。
    • @Robert #include
    猜你喜欢
    • 2020-06-12
    • 2023-04-02
    • 2013-07-15
    • 2015-02-05
    • 2011-11-09
    • 2021-09-10
    • 2019-12-05
    • 2014-12-21
    • 2013-07-06
    相关资源
    最近更新 更多