如果表不存在则创建_当创建一个文件的时候,操作系统发生了什么
操作文件是我們平時經常有的操作。但是我們可能并不是很了解他們原理,比如為什么刪除一個很大的文件,會非常快?創建一個文件的時候,系統發生了什么?為什么刪除的文件,還可以恢復?知其然知其所以然。我們一起深入探索文件系統的一些原理。這篇先分析一下創建文件的過程。
我們先看一下文件系統在硬盤中的布局。
我們再看一下文件系統在內存中的布局。
對著上面的圖,從左向右,我們看到
1 一個進程有一個文件描述符數組,這個描述符數組的元素,就是我們平時操作文件的時候,使用的那個fd。定義如下:
2 每個文件描述符只是索引,他對應的項指向一個file結構體,file結構體定義如下。
// 管理打開文件的內存屬性的結構,比如操作位置(inode沒有讀取操作位置這個概念,),實現系統進程共享inodestruct file { unsigned short f_mode; unsigned short f_flags; unsigned short f_count; struct m_inode * f_inode; off_t f_pos;};file結構體是和inode的作用是不一樣的,inode是更多的是存儲文件的一些持久化的數據,比如大小,時間、屬主,數據塊位置等。inode是存在硬盤中的。在操作的文件的時候才會加載到內存。如果有修改,需要回寫硬盤。file存儲的是文件臨時的元數據,他只存在內存里。比如一個文件當前讀寫位置,打開模式等等。關閉文件后就會丟失這些數據。
3 在文件系統中,每一個文件都對應一個inode結構體。inode保存了一個文件的元數據,包括大小,時間,屬主,塊號等等。inode存在于硬盤和內存,內存的inode叫m_inode,他的部分屬性和硬盤inode一一對應(硬盤inode叫d_inode),還有一些是只存在內存中的屬性。我們看一下inode在硬盤中的布局。
了解一系列結構體后,我們開始分析創建文件的這個過程。主要是兩件事情,第一,判斷文件是否存在,如果不存在則開始創建。
1 根據路徑找到最后一級目錄對應的inode節點。目錄其實也是文件,他和一般文件的區別是,一般文件存儲的是用戶數據,目錄文件存儲的是文件信息。目錄文件里存儲的數據就是一個對象數組,每個元素保存了文件名和inode節點號。
// 目錄項結構struct dir_entry { // inode號 unsigned short inode; // 文件名 char name[NAME_LEN];};假設我們找/a/b/hello.txt這個文件。因為/是根文件系統的根路徑,他在文件系統初始化的時候,根文件系統會從固定的位置(第一個inode節點),把他對應的inode結構體加載到內存中。我們根據根inode,就知道根目錄下面有多少dir_entry,然后逐個比較找到目錄a對應的dir_entry,從dir_entry中得到目錄a的inode號,再根據a的inode號把inode結構體從硬盤中加載到內存,繼續這個過程,直到最后找到hello.txt。
2 所以我們從一個目錄下找一個目錄或者文件的時候,其實就是遍歷這個數組,對比name是否一樣,是的話根據inode號取出inode結構體,從而取得文件數據。
3 因為我們是創建文件,所以是肯定找不到的。
4 上面已經解釋過,一個文件對應一個inode。現在我們創建一個文件,那自然,我們就要先在硬盤中申請一個inode,并且修改文件系統的元數據inode位圖,即這個inode被使用了。然后再在內存中申請一個m_inode。供用戶操作文件的。至此,創建文件就完成了。我們發現,創建一個文件,底層發生的事情其實就是在硬盤申請一個inode就可以了。
5 當我們開始操作m_inode對應的文件的時候。比如寫入。回歸上面的inode結構體可以發現,這時候文件其實是沒有被分配硬盤空間的。現在需要寫入,那首先就要先在硬盤中申請一塊空間。并修改塊位圖信息。然后申請一塊和該硬盤塊關聯的內存塊,用戶寫入的數據就存在該內存塊中,系統會定時回寫到硬盤中對應的塊。
這就是創建一個文件的大致過程。
總結
以上是生活随笔為你收集整理的如果表不存在则创建_当创建一个文件的时候,操作系统发生了什么的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 伪静态 获取当前页面路径_织梦移
- 下一篇: java拆分任意五位数_五位数拆分出各位