艹,檔案找不到!
談檔案異常前,先要給各位複習一下磁碟 IO 的知識,說到 IO,就不得不提一下計算機的儲存系統體系,主要分為 CPU、記憶體、磁碟,而磁碟又分為機械磁碟和固態硬碟。一般來說,離 CPU 越近,價格越貴,速度越快,容量越小;反之,離 CPU 越遠,價格越便宜,速度越慢,容量越大,見下圖。
機械磁碟讀寫一般以毫秒為單位,並且順序讀寫效能高於隨機讀寫,有的同學可能會問為什麼順序讀寫的效能要好些呢?主要跟機械磁碟的結構有關係「見下圖」,隨機讀寫實際是要不斷旋轉磁頭、扇區從而來找到對應的位置,因此效能較低。

在這裡,我們可以聯想到經常使用的資料庫,它的耗時一般主要發生在查詢的過程中,一般的調優也就是減少隨機 IO 的次數。各位讀者可以思考一下 SQL/">MySQL 是怎麼減少 IO 次數的呢?
對於固態硬碟來說,它是用固態電子儲存晶片陣列而製成的硬碟,由控制單元和儲存單元組成,沒有機械旋轉,因此,在效能上遠超過機械硬碟。
下面來聊聊幾個分析 IO 效能的工具。
首先,我們要知道磁碟的整體情況,才好對症下藥,那麼就離不開兩個命令 fdisk 和 df 。

從上圖我們可以得出這臺電腦的磁碟大小、有多少個扇區、每個扇區的大小以及使用了多少。
接著,我們需要分析 CPU 使用率、記憶體使用、虛擬記憶體交換、IO 讀寫情況等,如果是老讀者的話,應該還記得我之前給各位推薦的牛逼工具 vmstat 。

如果你關注的點是伺服器 IO 的讀寫效能,那麼你主要關注 b、bi、bo 及 wa的值,如果讀請求大,那麼 b、bi 及 wa 的值會比較大,反之,如果寫請求大,那麼 b、bo 及 wa 的值會比較大。
最後,給各位介紹兩款更加專業的工具 iostat 和 iotop ,見下圖你便知道它的牛逼之處了。

從上圖中,我們可以看到每秒讀寫大小、tps 以及 CPU 的一些情況。
這裡 iotop ,顧名思義,便是用於定位分析某個程序的 IO 狀況使用的,見下圖。

說完磁碟,咱們再說說檔案,對於檔案而言,主要就是檔案許可權、屬性以及資料「它們儲存在不同的地方」,見下圖「來自網路」。

下圖各各位展示一下整個 Linux 系統的目錄結構。

對了,之前有讀者問我 怎麼在 Linux 上判斷一個檔案是否是病毒? 這裡統一回答一下。
方法 1:可以直接比對檔案的 MD5 值,或者直接把檔案拿到線上病毒掃描網站上去掃一下。
方法 2:
用 file 命令快速識別檔案型別 file bashd;
用 xxd 命令檢視檔案十六進位制內容 xxd bashd | head xxd bashd | grep socket;
用 strings 命令快速識別檔案大體功能 strings bashd;
用 readelf 或 greadelf 命令繼續深入挖掘檔案資訊 readelf -a bashd;
到這裡,相信你應該對 Linux 的磁碟系統和檔案都有所瞭解了。接下來給大家講一下我們經常會遇到的一個異常 FileNotFoundException 。
該異常在 JDK 1.0 版本便存在了,擴充套件了 IOException,實現了序列化介面,取證見下圖。

在什麼情況下,會丟擲該異常呢?
-
開啟指定路徑名失敗時;
-
在只有只讀許可權的檔案中寫入;
-
該檔案不允許任何程式讀;
接著,依次舉例來說明一下。
下圖的程式碼實現讀取一個檔案的全部內容。

如果檔案不存在,則會丟擲:

下圖的程式碼實現在檔案的末尾新增一個字串。

如果檔案沒有寫入許可權,則丟擲:

如果檔案是一個目錄,則丟擲:

如何處理 FileNotFoundException 呢?
-
驗證指定的的檔案或目錄是否正確。
-
首先檢查檔案的許可權是否正確,其次,檢查該檔案當前是否正在由另一個應用程式使用。
-
如果指定的檔案是目錄,則必須更改檔名或刪除現有目錄。
根據以往經驗,在程式中,儘量使用絕對路徑,少用相對路徑。檔案異常還是相對比較好排查的,但是 IO 效能的問題排查起來,就沒有那麼容易了。