首页 > 解决方案 > 检索磁盘上文件的物理地址

问题描述

使用 Windows API,我正在尝试编写一个程序来从磁盘读取数据。我设法使用CreateFile访问驱动器的内容,并且能够搜索它。假设该磁盘上有一些文件并且我知道它们的路径,但我实际上对它们的物理位置感兴趣。

我的问题是:是否可以在不搜索整个驱动​​器的情况下检索文件(或它们所在的扇区)的物理位置或地址以及它们在驱动器上的存储位置?如果是这样,我应该使用哪些功能?使用SetFilePointerFindFirstFile似乎也不能解决问题。

标签: c++windowswinapifileapi

解决方案


任何文件系统的全部意义在于抽象物理磁盘扇区并为您提供更高级别的抽象(称为文件)。所以“是否可以检索物理位置”的答案应该是否定的!(一般来说); 某些代码甚至可能移动文件的扇区(例如磁盘碎片整理程序,您可以想象它与您的程序同时运行,即使不推荐这样做..)

有关更多信息,请阅读有关文件系统文件的 wikipages ,然后阅读一本好书,例如操作系统:三个简单的部分

请注意,通过使用文件,如果文件路径、内容和元数据保持不变,您希望程序在将文件系统移动到不同的磁盘后表现相似。特别是,您可能有两个具有不同几何形状或容量的外部 USB磁盘外壳具有相同的文件内容(甚至可能在不同的文件系统中,例如一个上的 VFAT 和另一个上的 NTFS),然后您希望您的程序在访问时表现相同此类文件(在第一个或第二个框中)。无论插入什么盒子,您的程序都会(例如)访问同一个F:\MyDir\MyFile.dat文件。作为文件系统,这两个框看起来是相同的。在物理扇区级别,数据的组织方式非常不同。

顺便说一句,文件系统中文件的物理组织因文件系统而异。你可以在你的机器上使用一些Ext3文件系统(因为有适用于 Windows 的Ext3 驱动程序)——这对于在双启动 PC 上的 Linux 和 Windows 之间共享一些数据实际上很有用——并且文件组织不同于FAT的或一个NTFS的。

您可能会通过某种方式查询内核以获取实际的物理扇区位置。但是我不确定它是否适用于所有文件系统(对于某些远程 NFS 而言,扇区位置的含义是什么)。并且这些信息在您的程序获取之前可能已经过时(例如,如果某些碎片整理程序正在并行工作)。此外,其他进程可以同时访问和修改同一个文件系统(这样元数据(例如扇区位置)将在您的进程计划再次运行时过时)。

在 Windows 和类 Unix 系统上,文件系统代码在内核中运行。当您的进程未运行时,其他进程可以使用相同的代码(和相同的文件系统)。Windows 和 Unix 都具有抢占式调度,因此您无法保证您的进程在其他进程使用相同的文件系统之前再次以用户模式运行。

请记住,在实践中,您的文件数据通常保留在页面缓存中。这就是为什么在连续多次访问同一个文件时(例如,在同一个文件上运行同一个程序两次,相隔几秒钟;通常是第二次运行保持磁盘静默,因为文件数据已经在 RAM 中)。

在评论中你提到你想要

查看文件的数据,例如查看数据在删除或修改时会发生什么。

但这应该在文件系统级别起作用。Linux 有inotify(7)工具(它们可以在大多数本地文件系统上工作,例如 Ext4 或 BTRFS,但不能在远程文件系统 à la nfs(5)上工作,也不能在伪文件系统上工作 à la proc(5))。我不知道 Windows 是否有类似于 Linux 的东西inotify(但可能的,至少在某些情况下)。

您可能应该考虑使用一些数据库(可能像sqlite一样简单),并且可能需要ACID属性(然后使用一些真正的RDBMS,如 PostGreSQL)。使用PostGreSQL,您可能会使用TRIGGERs 来了解某些数据已更改,即使某些其他程序更改了同一数据库。

您还可以做一些文件锁定,并采用每个访问您的特定文件的程序都应该适当地锁定它的约定。


推荐阅读