1. 程式人生 > >文件內部修改之後編輯器(vim)寫回

文件內部修改之後編輯器(vim)寫回

0kb bbs 自己的 再次 normal fde crt top info

一、文件中間修改寫回
這個不是問題,只是一個偶爾想起的一個事兒。因為我經常看帖子回帖的時候看到精彩的內容都會記錄到一個txt文件中,而且我還有一個好習慣,就是每次把新收集的內容放在文件的開始而不是像論壇的帖子一樣後來的回復追加在最後,因為我還有一個習慣,看這個文件都是從後向前看的,所以也沒有問題。
隨著收集內容的增加,這個文件就變得越來越大,到底有多大呢?例如我現在已經收集了200KB,由於之前剛壞掉了一塊硬盤,所以丟失了之前的收集。每次我把新的內容寫入文件的開始的時候,經常喜歡隨手按下Ctrl+S來保存一下。這裏使用的是文本文件而不是word文檔,所以這個操作還是有其必要性的。
鋪墊了這麽多,想說的問題是,後來我就發現,當文件變大之後,我在文件的開始打幾個回車的時候就可以感覺到它的卡。再後來我就想,如果我在這個文件的開始只添加了哪怕一個字,文件大小為200KB,那麽是不是這200KB+1字節會被逐個再次寫入硬盤?可以想象,這個操作還是很耗時的,雖然那原始的200KB都是無辜的,就是因為這一個字符的“加塞”,導致了這200KB依次後移,進而這個文件占用的所有的扇區都會被蹂躪一遍

。這個是一個直觀的想法,因為一般直觀的想法是不一定準確的,所以最好找一個文件測試一下,找了一個大概168KB的RFC文檔測試了一下。
二、測試結果
使用windows下的vim編輯器來進行一個調試,然後在vim73\src\fileio.c文件buf_write_bytes函數的地方打斷點,在文件的最開始添加一個字符,執行wq寫回修改,兩次斷點之間通過dir 看文件大小的變化

技術分享圖片

可以看到文件大小在執行一次buf_write_bytes函數之後增加8KB,而修改之後的內容則是保存在了一個臨時的“rfc793TRANSMISSION CONTROL PROTOCOL.txt~”文件中(當然這個可以不關心),然後以8KB為單位進行搬運。即便是8KB充分利用了扇區的批量寫入,但是這個寫入應該是不可避免的,也就是的確是會整個文件重新寫回。

三、windows下vim寫回的調用鏈
> vimd.exe!_write_nolock(int fh=3, const void * buf=0x011b7158, unsigned int cnt=8192) 行475 C
vimd.exe!_write(int fh=3, const void * buf=0x011b7158, unsigned int cnt=8192) 行75 + 0x11 字節 C
vimd.exe!buf_write_bytes(bw_info * ip=0x0012f3ec) 行5708 + 0x13 字節 C
vimd.exe!buf_write(file_buffer * buf=0x00ce8ce0, unsigned char * fname=0x00cef6d8, unsigned char * sfname=0x00cefab8, long start=1, long end=5247, exarg * eap=0x0012f780, int append=0, int forceit=0, int reset_changed=1, int filtering=0) 行4601 + 0xc 字節 C
vimd.exe!do_write(exarg * eap=0x0012f780) 行2707 + 0x38 字節 C
vimd.exe!ex_exit(exarg * eap=0x0012f780) 行6771 + 0x1e 字節 C
vimd.exe!do_one_cmd(unsigned char * * cmdlinep=0x0012fc1c, int sourcing=0, condstack * cstack=0x0012f904, unsigned char * (int, void *, int)* fgetline=0x005225fe, void * cookie=0x00000000) 行2656 + 0x12 字節 C
vimd.exe!do_cmdline(unsigned char * cmdline=0x00000000, unsigned char * (int, void *, int)* getline=0x005225fe, void * cookie=0x00000000, int flags=0) 行1126 + 0x25 字節 C
vimd.exe!nv_colon(cmdarg_S * cap=0x0012fd38) 行5320 + 0x1d 字節 C
vimd.exe!normal_cmd(oparg_S * oap=0x0012fde0, int toplevel=1) 行1190 + 0x12 字節 C
vimd.exe!main_loop(int cmdwin=0, int noexmode=0) 行1260 + 0xb 字節 C
vimd.exe!main() 行965 + 0x9 字節 C
vimd.exe!__tmainCRTStartup() 行266 + 0x19 字節 C
vimd.exe!mainCRTStartup() 行182 C
kernel32.dll!7c816fd7()
[下面的框架可能不正確和/或缺失,沒有為 kernel32.dll 加載符號]
vimd.exe!_read(int fh=-2096605813, void * buf=0x0000b8ba, unsigned int cnt=880017408) 行86 + 0x5d 字節 C
四、稍微引申一下
這個在很多的BBS中也可以看到,最新發表的評論一般都是在評論的最後面,這樣看比較符合大家的閱讀習慣,那就是從前到後的閱讀,對應的故事情節也是從開始到結束。但是從實現的角度來看,我覺得對文件操作每次追加在文件的最後從效率上講是有極大優勢的。我這裏只是在自己的PC上折騰,怎麽折騰也玩不出個花來,但是對於服務器來說,這個效率是必須要考慮的,因為現在很多服務器的瓶頸就在響應速度上,而且這個響應速度平時大家可能的確是感覺不到,但是到關鍵時期是影響和顯示產品質量的重要指標。例如網購網站搞一些限時促銷活動時,此時服務器的壓力就會很大;或者春運時網絡訂票系統等。很多東西就是這樣,60分大家都可以輕易得到,但是得到90分並不是僅僅比60分多了50%的概念,而可能是300%。例如一個基站,大家平時都可以打電話,但是大話務量時區別就可以看出來;而且一年之內的系統重啟次數也會有差別,雖然一般的基站一年可能也只有10次,但是和0比起來,是一個無限大的比例。

文件內部修改之後編輯器(vim)寫回