【发布时间】:2013-08-10 11:24:45
【问题描述】:
假设我们有一个已经存在的文件,比如<File>。此文件已由 C 程序打开以进行更新 (r+b)。我们使用fseek 导航到<File> 内的一个点,而不是它的末尾。现在我们开始使用fwrite/fputc 写入数据。请注意,我们不会删除以前存在于 <File> 中的任何数据...
系统如何处理这些写入?它是否将整个文件重写到磁盘中的另一个位置,现在包含新数据?它是否对文件进行分段并仅将新数据写入另一个位置(请记住,中间有一些可用空间)?它是否真的只覆盖已更改的部分?
有一个很好的理由问:在第一种情况下,如果您不断更新文件,系统可能会变慢。在第二种情况下,它可能会更快,但如果对许多文件执行,它会弄乱文件系统。在第三种情况下,特别是如果您有固态磁盘,一遍又一遍地更新文件的同一位置可能会使磁盘的该部分无用。
实际上,这就是我的问题的来源。我读过那篇文章,为了避免过度使用磁盘扇区,固态磁盘使用不同的技术将数据移动到使用较少的扇区。但是stdio 函数究竟是如何处理这种情况的呢?
提前感谢您的宝贵时间! :D
【问题讨论】:
-
像 stdio 这样的标准库不关心磁盘扇区。这就是司机的目的。此外,除了写入磁盘之外,还涉及更多内容,因为标准库只是将请求路由到操作系统,操作系统会检查访问权限(如果合适),然后将请求转发给驱动程序。 stdio 尽可能远离光盘。 stdio 甚至根本不知道数据是否已写入磁盘。它只是将其写入标准化流,可以是磁盘、网络或一些 RAM,或其他任何东西。它也可以是垃圾箱(又名 /dev/null):)
-
另外,当你删除和写入很多时,通常会出现碎片。在这种情况下,文件可能会“散落”在整个磁盘上,这会使访问速度变慢,因为驱动程序必须等待更多扇区被读取。当一个文件被写入一个连续的块中时,驱动程序可以处理它,以便光盘的旋转(如果它旋转)针对访问特定文件进行了优化。
-
谢谢!这很有帮助!!! :D 顺便问一下,你知道有什么方法(除了在汇编中编写操作系统)我们可以直接访问驱动器吗?
-
如何编写驱动程序取决于操作系统。但是,大多数驱动程序不再用汇编语言编写。您只需要小的汇编程序部分来执行其他方式不可用的指令,但大部分代码是 C 甚至 C++。对于 Windows,您可以查看可免费下载的 DDK。对于 Linux,源代码仍然可用。 :) 我会用谷歌搜索一些开源驱动程序(如果你走 Windows 路线)并看看它们。你可以看看 ReactOS,它是 Windows OSS 的替代品,并且是二进制兼容的,所以你肯定可以在他们的代码中找到一些东西。
-
现在我想起来了,您应该能够通过 UNC 路径(在 Windows 中)直接访问驱动器,当然在 Unix 中通过访问 /dev。如果您有适当的权限,您可以编写一个直接访问设备的用户空间应用程序,这样您就可以编写本地文件系统而无需编写完整的驱动程序。